1 SUBROUTINE pdsepsubtst( WKNOWN, JOBZ, RANGE, UPLO, N, VL, VU, IL,
2 $ IU, THRESH, ABSTOL, A, COPYA, Z, IA, JA,
3 $ DESCA, WIN, WNEW, IFAIL, ICLUSTR, GAP,
4 $ IPREPAD, IPOSTPAD, WORK, LWORK, LWORK1,
5 $ IWORK, LIWORK, RESULT, TSTNRM, QTQNRM,
15 CHARACTER JOBZ, RANGE, UPLO
16 INTEGER IA, IL, IPOSTPAD, IPREPAD, IU, JA, LIWORK,
17 $ LWORK, LWORK1, N, NOUT, RESULT
18 DOUBLE PRECISION ABSTOL, QTQNRM, THRESH, TSTNRM, VL, VU
21 INTEGER DESCA( * ), ICLUSTR( * ), IFAIL( * ),
23DOUBLE PRECISION A( * ), COPYA( * ), GAP( * ), WIN( * ),
24 $ WNEW( * ), WORK( * ), Z( * )
196 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
197 $ MB_, NB_, RSRC_, CSRC_, LLD_
198 PARAMETER ( BLOCK_CYCLIC_2D = 1, dlen_ = 9, dtype_ = 1,
199 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
200 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
201 DOUBLE PRECISION PADVAL, FIVE, NEGONE
202 PARAMETER ( PADVAL = 13.5285d+0, five = 5.0d+0,
205 PARAMETER ( IPADVAL = 927 )
208 LOGICAL MISSLARGEST, MISSSMALLEST
209 INTEGER I, IAM, INDIWRK, INFO, ISIZESUBTST, ISIZESYEVX,
210 $ isizetst, j, m, maxeigs, maxil, maxiu, maxsize,
211 $ minil, mq, mycol, myil, myrow, nclusters, np,
212 $ npcol, nprow, nq, nz, oldil, oldiu, oldnz, res,
213 $ sizechk, sizemqrleft, sizemqrright, sizeqrf,
214 $ sizeqtq, sizesubtst, sizesyevx, sizetms,
215 $ sizetst, valsize, vecsize
216 DOUBLE PRECISION EPS, EPSNORMA, ERROR, MAXERROR, MAXVU,
217 $ MINERROR, MINVL, NORMWIN, OLDVL, OLDVU, ORFAC,
221 INTEGER DESCZ( DLEN_ ), DSEED( 4 ), ITMP( 2 )
227 DOUBLE PRECISION PDLAMCH, PDLANSY
228 EXTERNAL , NUMROC, PDLAMCH, PDLANSY
238 INTRINSIC abs,
max,
min, mod
242 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
244 CALL pdlasizesep( desca, iprepad, ipostpad, sizemqrleft,
245 $ sizemqrright, sizeqrf, sizetms, sizeqtq,
246 $ sizechk, sizesyevx, isizesyevx, sizesubtst,
247 $ isizesubtst, sizetst, isizetst )
251 eps = pdlamch( desca( ctxt_ ),
'Eps' )
252 safmin = pdlamch( desca( ctxt_ ),
'Safe min' )
254 normwin = safmin / eps
256 $ normwin =
max( abs( win( 1 ) ), abs( win( n ) ), normwin )
267 DO 10 i = 1, lwork1, 1
268 work( i+iprepad ) = 14.3d+0
270 DO 20 i = 1, liwork, 1
271 iwork( i+iprepad ) = 14
275 wnew( i+iprepad ) = 3.14159d+0
278 iclustr( 1+iprepad ) = 139
280 IF( lsame( jobz,
'N' ) )
THEN
283 IF( lsame( range,
'A' ) )
THEN
285 ELSE IF( lsame( range,
'I' ) )
THEN
286 maxeigs = iu - il + 1
288 minvl = vl - normwin*five*eps - abstol
289 maxvu = vu + normwin*five*eps + abstol
293 IF( win( i ).LT.minvl )
295 IF( win( i ).LE.maxvu )
299 maxeigs = maxiu - minil + 1
304 CALL descinit( descz, desca( m_ ), desca( n_ ), desca( mb_ ),
305 $ desca( nb_ ), desca( rsrc_ ), desca( csrc_ ),
306 $ desca( ctxt_ ), desca( lld_ ), info )
309 indiwrk = 1 + iprepad + nprow*npcol + 1
312 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
318 IF( myrow.GE.nprow .OR. myrow.LT.0 )
329 $ dseed, win, maxsize, vecsize, valsize )
331 np = numroc( n, desca( mb_ ), myrow, 0, nprow )
332 nq = numroc( n, desca( nb_ ), mycol, 0, npcol )
333 mq = numroc( maxeigs, desca( nb_ ), mycol, 0, npcol )
335 CALL dlacpy(
'A', np, nq, copya, desca( lld_ ), a( 1+iprepad ),
338 CALL pdfillpad( desca( ctxt_ ), np, nq, a, desca( lld_ ), iprepad,
341 CALL pdfillpad( descz( ctxt_ ), np, mq, z, descz( lld_ ), iprepad,
342 $ ipostpad, padval+1.0d+0 )
344 CALL pdfillpad( desca( ctxt_ ), n, 1, wnew, n, iprepad, ipostpad,
347 CALL pdfillpad( desca( ctxt_ ), nprow*npcol, 1, gap, nprow*npcol,
348 $ iprepad, ipostpad, padval+3.0d+0 )
350 CALL pdfillpad( desca( ctxt_ ), lwork1, 1, work, lwork1, iprepad,
351 $ ipostpad, padval+4.0d+0 )
353 CALL pifillpad( desca( ctxt_ ), liwork, 1, iwork, liwork, iprepad,
354 $ ipostpad, ipadval )
356 CALL pifillpad( desca( ctxt_ ), n, 1, ifail, n, iprepad, ipostpad,
359 CALL pifillpad( desca( ctxt_ ), 2*nprow*npcol, 1, iclustr,
360 $ 2*nprow*npcol, iprepad, ipostpad, ipadval )
366 DO 50 j = 1, maxeigs, 1
367 CALL pdelset( z( 1+iprepad ), i, j, desca, 13.0d+0 )
376 CALL pdsyevx( jobz, range, uplo, n, a( 1+iprepad ), ia, ja, desca,
377 $ vl, vu, il, iu, abstol, m, nz, wnew( 1+iprepad ),
378 $ orfac, z( 1+iprepad ), ia, ja, desca,
379 $ work( 1+iprepad ), lwork1, iwork( 1+iprepad ),
380 $ liwork, ifail( 1+iprepad ), iclustr( 1+iprepad ),
381 $ gap( 1+iprepad ), info )
385 IF( thresh.LE.0 )
THEN
388 CALL pdchekpad( desca( ctxt_ ),
'PDSYEVX-A', np, nq, a,
389 $ desca( lld_ ), iprepad, ipostpad, padval )
391 CALL pdchekpad( descz( ctxt_ ),
'PDSYEVX-Z', np, mq, z,
392 $ descz( lld_ ), iprepad, ipostpad,
395 CALL pdchekpad( desca( ctxt_ ),
'PDSYEVX-WNEW', n, 1, wnew, n,
396 $ iprepad, ipostpad, padval+2.0d+0 )
398 CALL pdchekpad( desca( ctxt_ ),
'PDSYEVX-GAP', nprow*npcol, 1,
399 $ gap, nprow*npcol, iprepad, ipostpad,
402 CALL pdchekpad( desca( ctxt_ ),
'PDSYEVX-WORK', lwork1, 1,
403 $ work, lwork1, iprepad, ipostpad,
406 CALL pichekpad( desca( ctxt_ ),
'PDSYEVX-IWORK', liwork, 1,
407 $ iwork, liwork, iprepad, ipostpad, ipadval )
409 CALL pichekpad( desca( ctxt_ ),
'PDSYEVX-IFAIL', n, 1, ifail,
410 $ n, iprepad, ipostpad, ipadval )
412 CALL pichekpad( desca( ctxt_ ),
'PDSYEVX-ICLUSTR',
413 $ 2*nprow*npcol, 1, iclustr, 2*nprow*npcol,
414 $ iprepad, ipostpad, ipadval
419 IF( lsame( range,
'A' ) )
THEN
421 $ dseed, wnew( 1+iprepad ), maxsize,
434 CALL igamn2d( desca( ctxt_ ),
'a',
' ', 1, 1, itmp, 1, 1, 1,
436 CALL igamx2d( desca( ctxt_ ),
'a',
' ', 1, 1, itmp( 2 ), 1, 1,
440 IF( itmp( 1 ).NE.itmp( 2 ) )
THEN
442 $
WRITE( nout, fmt = * )
443 $ 'different processes
return different info
'
445.EQ..OR..GT..OR..LT.
ELSE IF( MOD( INFO, 2 )1 INFO7 INFO0 )
448 $ WRITE( NOUT, FMT = 9999 )INFO
450.EQ..AND..GE.
ELSE IF( MOD( INFO / 2, 2 )1 LWORK1MAXSIZE ) THEN
452 $ WRITE( NOUT, FMT = 9996 )INFO
454.EQ..AND..GE.
ELSE IF( MOD( INFO / 4, 2 )1 LWORK1VECSIZE ) THEN
456 $ WRITE( NOUT, FMT = 9996 )INFO
461 IF( LSAME( JOBZ, 'v.AND..NE.
' ) ( ICLUSTR( 1+IPREPAD )
462.AND..NE.
$ 0 ) ( MOD( INFO / 2, 2 )1 ) ) THEN
464 $ WRITE( NOUT, FMT = 9995 )
470.LT..OR..GT.
IF( ( M0 ) ( MN ) ) THEN
472 $ WRITE( NOUT, FMT = 9994 )
474 ELSE IF( LSAME( RANGE, 'a.AND..NE.
' ) ( MN ) ) THEN
476 $ WRITE( NOUT, FMT = 9993 )
478 ELSE IF( LSAME( RANGE, 'i.AND..NE.
' ) ( MIU-IL+1 ) ) THEN
480 $ WRITE( NOUT, FMT = 9992 )
482 ELSE IF( LSAME( JOBZ, 'v.AND.
' )
483.NOT.
$ ( ( LSAME( RANGE, 'v.AND..NE.
' ) ) ) ( MNZ ) )
486 $ WRITE( NOUT, FMT = 9991 )
492 IF( LSAME( JOBZ, 'v
' ) ) THEN
493 IF( LSAME( RANGE, 'v
' ) ) THEN
496 $ WRITE( NOUT, FMT = 9990 )
499.LT..AND..NE.
IF( NZM MOD( INFO / 4, 2 )1 ) THEN
501 $ WRITE( NOUT, FMT = 9989 )
507 $ WRITE( NOUT, FMT = 9988 )
512.EQ.
IF( RESULT0 ) THEN
519 CALL IGAMN2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP, 1, 1, 1,
521 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP( 2 ), 1,
524.NE.
IF( ITMP( 1 )ITMP( 2 ) ) THEN
526 $ WRITE( NOUT, FMT = 9987 )
533 WORK( I ) = WNEW( I+IPREPAD )
534 WORK( I+M ) = WNEW( I+IPREPAD )
537 CALL DGAMN2D( DESCA( CTXT_ ), 'a
', ' ', M, 1, WORK, M, 1,
539 CALL DGAMX2D( DESCA( CTXT_ ), 'a
', ' ', M, 1,
540 $ WORK( 1+M ), M, 1, 1, -1, -1, 0 )
544.EQ..AND.
IF( RESULT0 ( ABS( WORK( I )-WORK( M+
545.GT.
$ I ) )FIVE*EPS*ABS( WORK( I ) ) ) ) THEN
547 $ WRITE( NOUT, FMT = 9986 )
556 IF( LSAME( JOBZ, 'v
' ) ) THEN
558 DO 90 I = 0, NPROW*NPCOL - 1
559.EQ.
IF( ICLUSTR( 1+IPREPAD+2*I )0 )
561 NCLUSTERS = NCLUSTERS + 1
564 ITMP( 1 ) = NCLUSTERS
565 ITMP( 2 ) = NCLUSTERS
567 CALL IGAMN2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP, 1, 1, 1,
569 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP( 2 ), 1,
572.NE.
IF( ITMP( 1 )ITMP( 2 ) ) THEN
574 $ WRITE( NOUT, FMT = 9985 )
580 DO 110 I = 1, NCLUSTERS
581 IWORK( INDIWRK+I ) = ICLUSTR( I+IPREPAD )
582 IWORK( INDIWRK+I+NCLUSTERS ) = ICLUSTR( I+IPREPAD )
584 CALL IGAMN2D( DESCA( CTXT_ ), 'a
', ' ', NCLUSTERS*2+1, 1,
585 $ IWORK( INDIWRK+1 ), NCLUSTERS*2+1, 1, 1,
587 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', NCLUSTERS*2+1, 1,
588 $ IWORK( INDIWRK+1+NCLUSTERS ),
589 $ NCLUSTERS*2+1, 1, 1, -1, -1, 0 )
592 DO 120 I = 1, NCLUSTERS
593.EQ..AND..NE.
IF( RESULT0 IWORK( INDIWRK+I )
594 $ IWORK( INDIWRK+NCLUSTERS+I ) ) THEN
596 $ WRITE( NOUT, FMT = 9984 )
601.NE.
IF( ICLUSTR( 1+IPREPAD+NCLUSTERS*2 )0 ) THEN
603 $ WRITE( NOUT, FMT = 9983 )
610 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, RESULT, 1, 1, 1,
620 EPSNORMA = PDLANSY( 'i
', UPLO, N, COPYA, IA, JA, DESCA,
634 IF( LSAME( JOBZ, 'v
' ) ) THEN
638 CALL PDFILLPAD( DESCA( CTXT_ ), SIZECHK, 1, WORK, SIZECHK,
639 $ IPREPAD, IPOSTPAD, 4.3D+0 )
641 CALL PDSEPCHK( N, NZ, COPYA, IA, JA, DESCA,
642 $ MAX( ABSTOL+EPSNORMA, SAFMIN ), THRESH,
643 $ Z( 1+IPREPAD ), IA, JA, DESCZ,
644 $ A( 1+IPREPAD ), IA, JA, DESCA,
645 $ WNEW( 1+IPREPAD ), WORK( 1+IPREPAD ),
646 $ SIZECHK, TSTNRM, RES )
648 CALL PDCHEKPAD( DESCA( CTXT_ ), 'pdsepchk-work
', SIZECHK, 1,
649 $ WORK, SIZECHK, IPREPAD, IPOSTPAD, 4.3D+0 )
656 CALL PDFILLPAD( DESCA( CTXT_ ), SIZEQTQ, 1, WORK, SIZEQTQ,
657 $ IPREPAD, IPOSTPAD, 4.3D+0 )
660 CALL PDSEPQTQ( N, NZ, THRESH, Z( 1+IPREPAD ), IA, JA, DESCZ,
661 $ A( 1+IPREPAD ), IA, JA, DESCA,
662 $ IWORK( 1+IPREPAD+1 ), ICLUSTR( 1+IPREPAD ),
663 $ GAP( 1+IPREPAD ), WORK( IPREPAD+1 ), SIZEQTQ,
664 $ QTQNRM, INFO, RES )
666 CALL PDCHEKPAD( DESCA( CTXT_ ), 'pdsepqtq-work
', SIZEQTQ, 1,
667 $ WORK, SIZEQTQ, IPREPAD, IPOSTPAD, 4.3D+0 )
674 $ WRITE( NOUT, FMT = 9998 )INFO
687 IF( LSAME( RANGE, 'v
' ) ) THEN
692 IF( LSAME( RANGE, 'a
' ) ) THEN
704 DO 140 MYIL = MINIL, MAXIL
709 MISSSMALLEST = .TRUE.
710.NOT.
IF( LSAME( RANGE, 'v.OR..EQ.
' ) ( MYIL1 ) )
711 $ MISSSMALLEST = .FALSE.
712.AND..LT.
IF( MISSSMALLEST ( WIN( MYIL-1 )VL+NORMWIN*
713 $ FIVE*THRESH*EPS ) )MISSSMALLEST = .FALSE.
715.NOT.
IF( LSAME( RANGE, 'v.OR..EQ.
' ) ( MYILMAXIL ) )
716 $ MISSLARGEST = .FALSE.
717.AND..GT.
IF( MISSLARGEST ( WIN( MYIL+M )VU-NORMWIN*FIVE*
718 $ THRESH*EPS ) )MISSLARGEST = .FALSE.
719.NOT.
IF( MISSSMALLEST ) THEN
720.NOT.
IF( MISSLARGEST ) THEN
725 ERROR = ABS( WIN( I+MYIL-1 )-WNEW( I+IPREPAD ) )
726 MAXERROR = MAX( MAXERROR, ERROR )
729 MINERROR = MIN( MAXERROR, MINERROR )
740 IF( LSAME( JOBZ, 'v.AND.
' ) LSAME( RANGE, 'a
' ) ) THEN
741.GT.
IF( MINERRORNORMWIN*FIVE*FIVE*THRESH*EPS ) THEN
743 $ WRITE( NOUT, FMT = 9997 )MINERROR, NORMWIN
747.GT.
IF( MINERRORNORMWIN*FIVE*THRESH*EPS ) THEN
749 $ WRITE( NOUT, FMT = 9997 )MINERROR, NORMWIN
758.NE..OR..NE..OR..NE..OR..NE.
IF( ILOLDIL IUOLDIU VLOLDVL VU
761 $ WRITE( NOUT, FMT = 9982 )
765 IF( LSAME( JOBZ, 'n.AND..NE.
' ) ( NZOLDNZ ) ) THEN
767 $ WRITE( NOUT, FMT = 9981 )
775 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, RESULT, 1, 1, 1, -1,
783 9999 FORMAT( 'pdsyevx returned info=
', I7 )
784 9998 FORMAT( 'pdsepqtq returned info=
', I7 )
785 9997 FORMAT( 'pdsepsubtst minerror =
', D11.2, ' normwin=
', D11.2 )
786 9996 FORMAT( 'pdsyevx returned info=
', I7,
787 $ ' despite adequate workspace
' )
788 9995 FORMAT( 'iclustr(1).NE.0 but mod(info/2,2).NE.1
' )
789 9994 FORMAT( 'm not in
the range 0 to n
' )
790 9993 FORMAT( 'm not equal to n
' )
791 9992 FORMAT( 'm not equal to iu-il+1
' )
792 9991 FORMAT( 'm not equal to nz
' )
793 9990 FORMAT( 'nz > m
' )
794 9989 FORMAT( 'nz < m
' )
795 9988 FORMAT( 'nz not equal to m
' )
796 9987 FORMAT( 'different processes
return different values
for m
' )
797 9986 FORMAT( 'different processes
return different eigenvalues
' )
798 9985 FORMAT( 'different processes
return ',
799 $ 'different numbers of clusters
' )
800 9984 FORMAT( 'different processes
return different clusters
' )
801 9983 FORMAT( 'iclustr not zero terminated
' )
802 9982 FORMAT( 'il, iu, vl or vu altered by
pdsyevx' )
803 9981 FORMAT( 'nz altered by
pdsyevx with jobz=n
' )