1*> \brief \b DCHKPP
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 DCHKPP( DOTYPE, NN, NVAL, NNS, NSVAL, THRESH, TSTERR,
12*                          NMAX, A, AFAC, AINV, B, X, XACT, WORK, RWORK,
13*                          IWORK, NOUT )
14*
15*       .. Scalar Arguments ..
16*       LOGICAL            TSTERR
17*       INTEGER            NMAX, NN, NNS, NOUT
18*       DOUBLE PRECISION   THRESH
19*       ..
20*       .. Array Arguments ..
21*       LOGICAL            DOTYPE( * )
22*       INTEGER            IWORK( * ), NSVAL( * ), NVAL( * )
23*       DOUBLE PRECISION   A( * ), AFAC( * ), AINV( * ), B( * ),
24*      $                   RWORK( * ), WORK( * ), X( * ), XACT( * )
25*       ..
26*
27*
28*> \par Purpose:
29*  =============
30*>
31*> \verbatim
32*>
33*> DCHKPP tests DPPTRF, -TRI, -TRS, -RFS, and -CON
34*> \endverbatim
35*
36*  Arguments:
37*  ==========
38*
39*> \param[in] DOTYPE
40*> \verbatim
41*>          DOTYPE is LOGICAL array, dimension (NTYPES)
42*>          The matrix types to be used for testing.  Matrices of type j
43*>          (for 1 <= j <= NTYPES) are used for testing if DOTYPE(j) =
44*>          .TRUE.; if DOTYPE(j) = .FALSE., then type j is not used.
45*> \endverbatim
46*>
47*> \param[in] NN
48*> \verbatim
49*>          NN is INTEGER
50*>          The number of values of N contained in the vector NVAL.
51*> \endverbatim
52*>
53*> \param[in] NVAL
54*> \verbatim
55*>          NVAL is INTEGER array, dimension (NN)
56*>          The values of the matrix dimension N.
57*> \endverbatim
58*>
59*> \param[in] NNS
60*> \verbatim
61*>          NNS is INTEGER
62*>          The number of values of NRHS contained in the vector NSVAL.
63*> \endverbatim
64*>
65*> \param[in] NSVAL
66*> \verbatim
67*>          NSVAL is INTEGER array, dimension (NNS)
68*>          The values of the number of right hand sides NRHS.
69*> \endverbatim
70*>
71*> \param[in] THRESH
72*> \verbatim
73*>          THRESH is DOUBLE PRECISION
74*>          The threshold value for the test ratios.  A result is
75*>          included in the output file if RESULT >= THRESH.  To have
76*>          every test ratio printed, use THRESH = 0.
77*> \endverbatim
78*>
79*> \param[in] TSTERR
80*> \verbatim
81*>          TSTERR is LOGICAL
82*>          Flag that indicates whether error exits are to be tested.
83*> \endverbatim
84*>
85*> \param[in] NMAX
86*> \verbatim
87*>          NMAX is INTEGER
88*>          The maximum value permitted for N, used in dimensioning the
89*>          work arrays.
90*> \endverbatim
91*>
92*> \param[out] A
93*> \verbatim
94*>          A is DOUBLE PRECISION array, dimension
95*>                      (NMAX*(NMAX+1)/2)
96*> \endverbatim
97*>
98*> \param[out] AFAC
99*> \verbatim
100*>          AFAC is DOUBLE PRECISION array, dimension
101*>                      (NMAX*(NMAX+1)/2)
102*> \endverbatim
103*>
104*> \param[out] AINV
105*> \verbatim
106*>          AINV is DOUBLE PRECISION array, dimension
107*>                      (NMAX*(NMAX+1)/2)
108*> \endverbatim
109*>
110*> \param[out] B
111*> \verbatim
112*>          B is DOUBLE PRECISION array, dimension (NMAX*NSMAX)
113*>          where NSMAX is the largest entry in NSVAL.
114*> \endverbatim
115*>
116*> \param[out] X
117*> \verbatim
118*>          X is DOUBLE PRECISION array, dimension (NMAX*NSMAX)
119*> \endverbatim
120*>
121*> \param[out] XACT
122*> \verbatim
123*>          XACT is DOUBLE PRECISION array, dimension (NMAX*NSMAX)
124*> \endverbatim
125*>
126*> \param[out] WORK
127*> \verbatim
128*>          WORK is DOUBLE PRECISION array, dimension
129*>                      (NMAX*max(3,NSMAX))
130*> \endverbatim
131*>
132*> \param[out] RWORK
133*> \verbatim
134*>          RWORK is DOUBLE PRECISION array, dimension
135*>                      (max(NMAX,2*NSMAX))
136*> \endverbatim
137*>
138*> \param[out] IWORK
139*> \verbatim
140*>          IWORK is INTEGER array, dimension (NMAX)
141*> \endverbatim
142*>
143*> \param[in] NOUT
144*> \verbatim
145*>          NOUT is INTEGER
146*>          The unit number for output.
147*> \endverbatim
148*
149*  Authors:
150*  ========
151*
152*> \author Univ. of Tennessee
153*> \author Univ. of California Berkeley
154*> \author Univ. of Colorado Denver
155*> \author NAG Ltd.
156*
157*> \ingroup double_lin
158*
159*  =====================================================================
160      SUBROUTINE DCHKPP( DOTYPE, NN, NVAL, NNS, NSVAL, THRESH, TSTERR,
161     $                   NMAX, A, AFAC, AINV, B, X, XACT, WORK, RWORK,
162     $                   IWORK, NOUT )
163*
164*  -- LAPACK test routine --
165*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
166*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
167*
168*     .. Scalar Arguments ..
169      LOGICAL            TSTERR
170      INTEGER            NMAX, NN, NNS, NOUT
171      DOUBLE PRECISION   THRESH
172*     ..
173*     .. Array Arguments ..
174      LOGICAL            DOTYPE( * )
175      INTEGER            IWORK( * ), NSVAL( * ), NVAL( * )
176      DOUBLE PRECISION   A( * ), AFAC( * ), AINV( * ), B( * ),
177     $                   RWORK( * ), WORK( * ), X( * ), XACT( * )
178*     ..
179*
180*  =====================================================================
181*
182*     .. Parameters ..
183      DOUBLE PRECISION   ZERO
184      PARAMETER          ( ZERO = 0.0D+0 )
185      INTEGER            NTYPES
186      PARAMETER          ( NTYPES = 9 )
187      INTEGER            NTESTS
188      PARAMETER          ( NTESTS = 8 )
189*     ..
190*     .. Local Scalars ..
191      LOGICAL            ZEROT
192      CHARACTER          DIST, PACKIT, TYPE, UPLO, XTYPE
193      CHARACTER*3        PATH
194      INTEGER            I, IMAT, IN, INFO, IOFF, IRHS, IUPLO, IZERO, K,
195     $                   KL, KU, LDA, MODE, N, NERRS, NFAIL, NIMAT, NPP,
196     $                   NRHS, NRUN
197      DOUBLE PRECISION   ANORM, CNDNUM, RCOND, RCONDC
198*     ..
199*     .. Local Arrays ..
200      CHARACTER          PACKS( 2 ), UPLOS( 2 )
201      INTEGER            ISEED( 4 ), ISEEDY( 4 )
202      DOUBLE PRECISION   RESULT( NTESTS )
203*     ..
204*     .. External Functions ..
205      DOUBLE PRECISION   DGET06, DLANSP
206      EXTERNAL           DGET06, DLANSP
207*     ..
208*     .. External Subroutines ..
209      EXTERNAL           ALAERH, ALAHD, ALASUM, DCOPY, DERRPO, DGET04,
210     $                   DLACPY, DLARHS, DLATB4, DLATMS, DPPCON, DPPRFS,
211     $                   DPPT01, DPPT02, DPPT03, DPPT05, DPPTRF, DPPTRI,
212     $                   DPPTRS
213*     ..
214*     .. Scalars in Common ..
215      LOGICAL            LERR, OK
216      CHARACTER*32       SRNAMT
217      INTEGER            INFOT, NUNIT
218*     ..
219*     .. Common blocks ..
220      COMMON             / INFOC / INFOT, NUNIT, OK, LERR
221      COMMON             / SRNAMC / SRNAMT
222*     ..
223*     .. Intrinsic Functions ..
224      INTRINSIC          MAX
225*     ..
226*     .. Data statements ..
227      DATA               ISEEDY / 1988, 1989, 1990, 1991 /
228      DATA               UPLOS / 'U', 'L' / , PACKS / 'C', 'R' /
229*     ..
230*     .. Executable Statements ..
231*
232*     Initialize constants and the random number seed.
233*
234      PATH( 1: 1 ) = 'Double precision'
235      PATH( 2: 3 ) = 'PP'
236      NRUN = 0
237      NFAIL = 0
238      NERRS = 0
239      DO 10 I = 1, 4
240         ISEED( I ) = ISEEDY( I )
241   10 CONTINUE
242*
243*     Test the error exits
244*
245      IF( TSTERR )
246     $   CALL DERRPO( PATH, NOUT )
247      INFOT = 0
248*
249*     Do for each value of N in NVAL
250*
251      DO 110 IN = 1, NN
252         N = NVAL( IN )
253         LDA = MAX( N, 1 )
254         XTYPE = 'N'
255         NIMAT = NTYPES
256         IF( N.LE.0 )
257     $      NIMAT = 1
258*
259         DO 100 IMAT = 1, NIMAT
260*
261*           Do the tests only if DOTYPE( IMAT ) is true.
262*
263            IF( .NOT.DOTYPE( IMAT ) )
264     $         GO TO 100
265*
266*           Skip types 3, 4, or 5 if the matrix size is too small.
267*
268            ZEROT = IMAT.GE.3 .AND. IMAT.LE.5
269            IF( ZEROT .AND. N.LT.IMAT-2 )
270     $         GO TO 100
271*
272*           Do first for UPLO = 'U', then for UPLO = 'L'
273*
274            DO 90 IUPLO = 1, 2
275               UPLO = UPLOS( IUPLO )
276               PACKIT = PACKS( IUPLO )
277*
278*              Set up parameters with DLATB4 and generate a test matrix
279*              with DLATMS.
280*
281               CALL DLATB4( PATH, IMAT, N, N, TYPE, KL, KU, ANORM, MODE,
282     $                      CNDNUM, DIST )
283*
284               SRNAMT = 'DLATMS'
285               CALL DLATMS( N, N, DIST, ISEED, TYPE, RWORK, MODE,
286     $                      CNDNUM, ANORM, KL, KU, PACKIT, A, LDA, WORK,
287     $                      INFO )
288*
289*              Check error code from DLATMS.
290*
291               IF( INFO.NE.0 ) THEN
292                  CALL ALAERH( PATH, 'DLATMS', INFO, 0, UPLO, N, N, -1,
293     $                         -1, -1, IMAT, NFAIL, NERRS, NOUT )
294                  GO TO 90
295               END IF
296*
297*              For types 3-5, zero one row and column of the matrix to
298*              test that INFO is returned correctly.
299*
300               IF( ZEROT ) THEN
301                  IF( IMAT.EQ.3 ) THEN
302                     IZERO = 1
303                  ELSE IF( IMAT.EQ.4 ) THEN
304                     IZERO = N
305                  ELSE
306                     IZERO = N / 2 + 1
307                  END IF
308*
309*                 Set row and column IZERO of A to 0.
310*
311                  IF( IUPLO.EQ.1 ) THEN
312                     IOFF = ( IZERO-1 )*IZERO / 2
313                     DO 20 I = 1, IZERO - 1
314                        A( IOFF+I ) = ZERO
315   20                CONTINUE
316                     IOFF = IOFF + IZERO
317                     DO 30 I = IZERO, N
318                        A( IOFF ) = ZERO
319                        IOFF = IOFF + I
320   30                CONTINUE
321                  ELSE
322                     IOFF = IZERO
323                     DO 40 I = 1, IZERO - 1
324                        A( IOFF ) = ZERO
325                        IOFF = IOFF + N - I
326   40                CONTINUE
327                     IOFF = IOFF - IZERO
328                     DO 50 I = IZERO, N
329                        A( IOFF+I ) = ZERO
330   50                CONTINUE
331                  END IF
332               ELSE
333                  IZERO = 0
334               END IF
335*
336*              Compute the L*L' or U'*U factorization of the matrix.
337*
338               NPP = N*( N+1 ) / 2
339               CALL DCOPY( NPP, A, 1, AFAC, 1 )
340               SRNAMT = 'DPPTRF'
341               CALL DPPTRF( UPLO, N, AFAC, INFO )
342*
343*              Check error code from DPPTRF.
344*
345               IF( INFO.NE.IZERO ) THEN
346                  CALL ALAERH( PATH, 'DPPTRF', INFO, IZERO, UPLO, N, N,
347     $                         -1, -1, -1, IMAT, NFAIL, NERRS, NOUT )
348                  GO TO 90
349               END IF
350*
351*              Skip the tests if INFO is not 0.
352*
353               IF( INFO.NE.0 )
354     $            GO TO 90
355*
356*+    TEST 1
357*              Reconstruct matrix from factors and compute residual.
358*
359               CALL DCOPY( NPP, AFAC, 1, AINV, 1 )
360               CALL DPPT01( UPLO, N, A, AINV, RWORK, RESULT( 1 ) )
361*
362*+    TEST 2
363*              Form the inverse and compute the residual.
364*
365               CALL DCOPY( NPP, AFAC, 1, AINV, 1 )
366               SRNAMT = 'DPPTRI'
367               CALL DPPTRI( UPLO, N, AINV, INFO )
368*
369*              Check error code from DPPTRI.
370*
371               IF( INFO.NE.0 )
372     $            CALL ALAERH( PATH, 'DPPTRI', INFO, 0, UPLO, N, N, -1,
373     $                         -1, -1, IMAT, NFAIL, NERRS, NOUT )
374*
375               CALL DPPT03( UPLO, N, A, AINV, WORK, LDA, RWORK, RCONDC,
376     $                      RESULT( 2 ) )
377*
378*              Print information about the tests that did not pass
379*              the threshold.
380*
381               DO 60 K = 1, 2
382                  IF( RESULT( K ).GE.THRESH ) THEN
383                     IF( NFAIL.EQ.0 .AND. NERRS.EQ.0 )
384     $                  CALL ALAHD( NOUT, PATH )
385                     WRITE( NOUT, FMT = 9999 )UPLO, N, IMAT, K,
386     $                  RESULT( K )
387                     NFAIL = NFAIL + 1
388                  END IF
389   60          CONTINUE
390               NRUN = NRUN + 2
391*
392               DO 80 IRHS = 1, NNS
393                  NRHS = NSVAL( IRHS )
394*
395*+    TEST 3
396*              Solve and compute residual for  A * X = B.
397*
398                  SRNAMT = 'DLARHS'
399                  CALL DLARHS( PATH, XTYPE, UPLO, ' ', N, N, KL, KU,
400     $                         NRHS, A, LDA, XACT, LDA, B, LDA, ISEED,
401     $                         INFO )
402                  CALL DLACPY( 'Full', N, NRHS, B, LDA, X, LDA )
403*
404                  SRNAMT = 'DPPTRS'
405                  CALL DPPTRS( UPLO, N, NRHS, AFAC, X, LDA, INFO )
406*
407*              Check error code from DPPTRS.
408*
409                  IF( INFO.NE.0 )
410     $               CALL ALAERH( PATH, 'DPPTRS', INFO, 0, UPLO, N, N,
411     $                            -1, -1, NRHS, IMAT, NFAIL, NERRS,
412     $                            NOUT )
413*
414                  CALL DLACPY( 'Full', N, NRHS, B, LDA, WORK, LDA )
415                  CALL DPPT02( UPLO, N, NRHS, A, X, LDA, WORK, LDA,
416     $                         RWORK, RESULT( 3 ) )
417*
418*+    TEST 4
419*              Check solution from generated exact solution.
420*
421                  CALL DGET04( N, NRHS, X, LDA, XACT, LDA, RCONDC,
422     $                         RESULT( 4 ) )
423*
424*+    TESTS 5, 6, and 7
425*              Use iterative refinement to improve the solution.
426*
427                  SRNAMT = 'DPPRFS'
428                  CALL DPPRFS( UPLO, N, NRHS, A, AFAC, B, LDA, X, LDA,
429     $                         RWORK, RWORK( NRHS+1 ), WORK, IWORK,
430     $                         INFO )
431*
432*              Check error code from DPPRFS.
433*
434                  IF( INFO.NE.0 )
435     $               CALL ALAERH( PATH, 'DPPRFS', INFO, 0, UPLO, N, N,
436     $                            -1, -1, NRHS, IMAT, NFAIL, NERRS,
437     $                            NOUT )
438*
439                  CALL DGET04( N, NRHS, X, LDA, XACT, LDA, RCONDC,
440     $                         RESULT( 5 ) )
441                  CALL DPPT05( UPLO, N, NRHS, A, B, LDA, X, LDA, XACT,
442     $                         LDA, RWORK, RWORK( NRHS+1 ),
443     $                         RESULT( 6 ) )
444*
445*                 Print information about the tests that did not pass
446*                 the threshold.
447*
448                  DO 70 K = 3, 7
449                     IF( RESULT( K ).GE.THRESH ) THEN
450                        IF( NFAIL.EQ.0 .AND. NERRS.EQ.0 )
451     $                     CALL ALAHD( NOUT, PATH )
452                        WRITE( NOUT, FMT = 9998 )UPLO, N, NRHS, IMAT,
453     $                     K, RESULT( K )
454                        NFAIL = NFAIL + 1
455                     END IF
456   70             CONTINUE
457                  NRUN = NRUN + 5
458   80          CONTINUE
459*
460*+    TEST 8
461*              Get an estimate of RCOND = 1/CNDNUM.
462*
463               ANORM = DLANSP( '1', UPLO, N, A, RWORK )
464               SRNAMT = 'DPPCON'
465               CALL DPPCON( UPLO, N, AFAC, ANORM, RCOND, WORK, IWORK,
466     $                      INFO )
467*
468*              Check error code from DPPCON.
469*
470               IF( INFO.NE.0 )
471     $            CALL ALAERH( PATH, 'DPPCON', INFO, 0, UPLO, N, N, -1,
472     $                         -1, -1, IMAT, NFAIL, NERRS, NOUT )
473*
474               RESULT( 8 ) = DGET06( RCOND, RCONDC )
475*
476*              Print the test ratio if greater than or equal to THRESH.
477*
478               IF( RESULT( 8 ).GE.THRESH ) THEN
479                  IF( NFAIL.EQ.0 .AND. NERRS.EQ.0 )
480     $               CALL ALAHD( NOUT, PATH )
481                  WRITE( NOUT, FMT = 9999 )UPLO, N, IMAT, 8,
482     $               RESULT( 8 )
483                  NFAIL = NFAIL + 1
484               END IF
485               NRUN = NRUN + 1
486   90       CONTINUE
487  100    CONTINUE
488  110 CONTINUE
489*
490*     Print a summary of the results.
491*
492      CALL ALASUM( PATH, NOUT, NFAIL, NRUN, NERRS )
493*
494 9999 FORMAT( ' UPLO = ''', A1, ''', N =', I5, ', type ', I2, ', test ',
495     $      I2, ', ratio =', G12.5 )
496 9998 FORMAT( ' UPLO = ''', A1, ''', N =', I5, ', NRHS=', I3, ', type ',
497     $      I2, ', test(', I2, ') =', G12.5 )
498      RETURN
499*
500*     End of DCHKPP
501*
502      END
503