1 SUBROUTINE pdseprsubtst( 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,
17 CHARACTER JOBZ, RANGE, UPLO
18 INTEGER IA, IL, IPOSTPAD, IPREPAD, IU, JA, LIWORK,
19 $ LWORK, LWORK1, N, NOUT, RESULT
20 DOUBLE PRECISION ABSTOL, QTQNRM, THRESH, TSTNRM, VL, VU
23 INTEGER DESCA( * ), ICLUSTR( * ), ( * ),
25 DOUBLE PRECISION A( * ), COPYA( * ), GAP( * ), WIN( * ),
26 $ WNEW( * ), ( * ), Z( * )
187 INTEGER DLEN_, CTXT_, M_, N_,
188 $ MB_, NB_, RSRC_, CSRC_, LLD_
189 PARAMETER ( DLEN_ = 9,
190 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
191 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
192 DOUBLE PRECISION PADVAL, FIVE, NEGONE
193 PARAMETER ( PADVAL = 13.5285d0, five = 5.0d0,
196 PARAMETER ( IPADVAL = 927 )
199 LOGICAL MISSLARGEST, MISSSMALLEST
200 INTEGER I, , INDIWRK, , ISIZESUBTST, ,
201 $ isizetst, j, m, maxeigs, maxil, maxiu, maxsize,
202 $ minil, mq, mycol, myil, myrow, nclusters, np,
203 $ npcol, nprow, nq, nz, oldil, oldiu, oldnz, res,
204 $ sizechk, sizemqrleft, sizemqrright, sizeqrf,
206 $ sizetst, valsize, vecsize
207 DOUBLE PRECISION EPS, EPSNORMA, ERROR, MAXERROR, MAXVU,
208 $ , MINVL, NORMWIN, OLDVL, OLDVU
212 INTEGER DESCZ( DLEN_ ), ISEED( 4 ), ITMP( 2 )
219 EXTERNAL LSAME, NUMROC, PDLAMCH, PDLANSY
229 INTRINSIC abs,
max,
min, mod
233 CALL pdlasizesepr( desca, iprepad, ipostpad, sizemqrleft,
234 $ sizemqrright, sizeqrf, sizetms, sizeqtq,
235 $ sizechk, sizeevr, isizeevr, sizesubtst,
236 $ isizesubtst, sizetst, isizetst )
240 eps = pdlamch( desca( ctxt_ ),
'Eps' )
241 safmin = pdlamch( desca( ctxt_ ),
'Safe min' )
243 normwin = safmin / eps
245 $ normwin =
max( abs( win( 1 ) ), abs( win( n ) ), normwin )
256 DO 10 i = 1, lwork1, 1
257 work( i+iprepad ) = 14.3d0
260 DO 20 i = 1, liwork, 1
261 iwork( i+iprepad ) = 14
265 wnew( i+iprepad ) = 3.14159d0
268 iclustr( 1+iprepad ) = 139
270 IF (lsame( range,
'V' ) )
THEN
274 IF( lsame( jobz,
'N' ) )
THEN
277 IF( lsame( range,
'A' ) )
THEN
279 ELSE IF( lsame( range,
'I' ) )
THEN
280 maxeigs = iu - il + 1
282 minvl = vl - normwin*five*eps - abstol
283 maxvu = vu + normwin*five*eps + abstol
289 IF( win( i ).LT.minvl )
291 IF( win( i ).LE.maxvu )
295 maxeigs = maxiu - minil + 1
300 CALL descinit( descz, desca( m_ ), desca( n_ ), desca( mb_ ),
301 $ desca( nb_ ), desca( rsrc_ ), desca( csrc_ ),
302 $ desca( ctxt_ ), desca( lld_ ), info )
305 indiwrk = 1 + iprepad + nprow*npcol + 1
308 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
314 IF( myrow.GE.nprow .OR. myrow.LT.0 )
321 $ iseed, win, maxsize, vecsize, valsize )
323 np = numroc( n, desca( mb_ ), myrow, 0, nprow )
324 nq = numroc( n, desca( nb_ ), mycol, 0, npcol )
325 mq = numroc( maxeigs, desca( nb_ ), mycol, 0, npcol )
327 CALL dlacpy(
'A', np, nq, copya, desca( lld_ ), a( 1+iprepad ),
330 CALL pdfillpad( desca( ctxt_ ), np, nq, a, desca( lld_ ), iprepad,
333 CALL pdfillpad( descz( ctxt_ ), np, mq, z, descz( lld_ ), iprepad,
334 $ ipostpad, padval+1.0d0 )
342 CALL pdfillpad( desca( ctxt_ ), n, 1, wnew, n, iprepad, ipostpad,
345 CALL pdfillpad( desca( ctxt_ ), nprow*npcol, 1, gap, nprow*npcol,
346 $ iprepad, ipostpad, padval+3.0d0 )
348 CALL pdfillpad( desca( ctxt_ ), lwork1, 1, work, lwork1, iprepad,
349 $ ipostpad, padval+4.0d0 )
351 CALL pifillpad( desca( ctxt_ ), liwork, 1, iwork, liwork, iprepad,
352 $ ipostpad, ipadval )
354 CALL pifillpad( desca( ctxt_ ), n, 1, ifail, n, iprepad, ipostpad,
357 CALL pifillpad( desca( ctxt_ ), 2*nprow*npcol, 1, iclustr,
358 $ 2*nprow*npcol, iprepad, ipostpad, ipadval )
364 DO 50 j = 1, maxeigs, 1
365 CALL pdelset( z( 1+iprepad ), i, j, desca, 13.0d0 )
379 CALL pdsyevr( jobz, range, uplo, n, a( 1+iprepad ), ia, ja, desca,
380 $ vl, vu, il, iu, m, nz, wnew( 1+iprepad ),
381 $ z( 1+iprepad ), ia, ja, desca,
382 $ work( 1+iprepad ), lwork1, iwork( 1+iprepad ),
396 iclustr( 1+iprepad ) = 0
398 IF( thresh.LE.0 )
THEN
401 CALL pdchekpad( desca( ctxt_ ),
'PDSYEVR-A', np, nq, a,
402 $ desca( lld_ ), iprepad, ipostpad, padval )
404 CALL pdchekpad( descz( ctxt_ ),
'PDSYEVR-Z', np, mq, z,
405 $ descz( lld_ ), iprepad, ipostpad,
408 CALL pdchekpad( desca( ctxt_ ),
'PDSYEVR-WNEW', n, 1, wnew, n,
409 $ iprepad, ipostpad, padval+2.0d0 )
411 CALL pdchekpad( desca( ctxt_ ),
'PDSYEVR-GAP', nprow*npcol, 1,
412 $ gap, nprow*npcol, iprepad, ipostpad,
415 CALL pdchekpad( desca( ctxt_ ),
'PDSYEVR-WORK', lwork1, 1,
416 $ work, lwork1, iprepad, ipostpad,
419 CALL pichekpad( desca( ctxt_ ),
'PDSYEVR-IWORK', liwork, 1,
420 $ iwork, liwork, iprepad, ipostpad, ipadval )
423 $ N, IPREPAD, IPOSTPAD, IPADVAL )
425 CALL PICHEKPAD( DESCA( CTXT_ ), 'pdsyevr-iclustr
',
426 $ 2*NPROW*NPCOL, 1, ICLUSTR, 2*NPROW*NPCOL,
427 $ IPREPAD, IPOSTPAD, IPADVAL )
431 IF( LSAME( RANGE, 'a
' ) ) THEN
432 CALL PDLASIZESYEVR( .TRUE., RANGE, N, DESCA, VL, VU, IL, IU,
433 $ ISEED, WNEW( 1+IPREPAD ), MAXSIZE,
443 CALL IGAMN2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP, 1, 1, 1,
445 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP( 2 ), 1, 1,
449.NE.
IF( ITMP( 1 )ITMP( 2 ) ) THEN
451 $ WRITE( NOUT, FMT = * )
452 $ 'different processes
return different info
'
454.EQ..OR..GT..OR..LT.
ELSE IF( MOD( INFO, 2 )1 INFO7 INFO0 )
457 $ WRITE( NOUT, FMT = 9999 )INFO
459.EQ..AND..GE.
ELSE IF( MOD( INFO / 2, 2 )1 LWORK1MAXSIZE ) THEN
461 $ WRITE( NOUT, FMT = 9996 )INFO
463.EQ..AND..GE.
ELSE IF( MOD( INFO / 4, 2 )1 LWORK1VECSIZE ) THEN
465 $ WRITE( NOUT, FMT = 9996 )INFO
469 IF( LSAME( JOBZ, 'v.AND..NE.
' ) ( ICLUSTR( 1+IPREPAD )
470.AND..NE.
$ 0 ) ( MOD( INFO / 2, 2 )1 ) ) THEN
472 $ WRITE( NOUT, FMT = 9995 )
478.LT..OR..GT.
IF( ( M0 ) ( MN ) ) THEN
480 $ WRITE( NOUT, FMT = 9994 )
481 WRITE( NOUT,*) 'm =
', M, '\n
', 'n =
', N
483 ELSE IF( LSAME( RANGE, 'a.AND..NE.
' ) ( MN ) ) THEN
485 $ WRITE( NOUT, FMT = 9993 )
487 ELSE IF( LSAME( RANGE, 'i.AND..NE.
' ) ( MIU-IL+1 ) ) THEN
489 WRITE( NOUT, FMT = 9992 )
490 WRITE( NOUT,*) 'il =
', IL, ' iu =
', IU, ' m =
', M
493 ELSE IF( LSAME( JOBZ, 'v.AND.
' )
494.NOT.
$ ( ( LSAME( RANGE, 'v.AND..NE.
' ) ) ) ( MNZ ) )
497 $ WRITE( NOUT, FMT = 9991 )
503 IF( LSAME( JOBZ, 'v
' ) ) THEN
504 IF( LSAME( RANGE, 'v
' ) ) THEN
507 $ WRITE( NOUT, FMT = 9990 )
510.LT..AND..NE.
IF( NZM MOD( INFO / 4, 2 )1 ) THEN
512 $ WRITE( NOUT, FMT = 9989 )
518 $ WRITE( NOUT, FMT = 9988 )
523.EQ.
IF( RESULT0 ) THEN
530 CALL IGAMN2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP, 1, 1, 1,
532 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP( 2 ), 1,
535.NE.
IF( ITMP( 1 )ITMP( 2 ) ) THEN
537 $ WRITE( NOUT, FMT = 9987 )
544 WORK( I ) = WNEW( I+IPREPAD )
545 WORK( I+M ) = WNEW( I+IPREPAD )
548 CALL DGAMN2D( DESCA( CTXT_ ), 'a
', ' ', M, 1, WORK, M, 1,
550 CALL DGAMX2D( DESCA( CTXT_ ), 'a
', ' ', M, 1,
551 $ WORK( 1+M ), M, 1, 1, -1, -1, 0 )
554.EQ..AND.
IF( RESULT0 ( ABS( WORK( I )-WORK( M+
555.GT.
$ I ) )FIVE*EPS*ABS( WORK( I ) ) ) ) THEN
557 $ WRITE( NOUT, FMT = 9986 )
566 IF( LSAME( JOBZ, 'v
' ) ) THEN
568 DO 90 I = 0, NPROW*NPCOL - 1
569.EQ.
IF( ICLUSTR( 1+IPREPAD+2*I )0 )
571 NCLUSTERS = NCLUSTERS + 1
574 ITMP( 1 ) = NCLUSTERS
575 ITMP( 2 ) = NCLUSTERS
577 CALL IGAMN2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP, 1, 1, 1,
579 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP( 2 ), 1,
582.NE.
IF( ITMP( 1 )ITMP( 2 ) ) THEN
584 $ WRITE( NOUT, FMT = 9985 )
590 DO 110 I = 1, NCLUSTERS
591 IWORK( INDIWRK+I ) = ICLUSTR( I+IPREPAD )
592 IWORK( INDIWRK+I+NCLUSTERS ) = ICLUSTR( I+IPREPAD )
594 CALL IGAMN2D( DESCA( CTXT_ ), 'a
', ' ', NCLUSTERS*2+1, 1,
595 $ IWORK( INDIWRK+1 ), NCLUSTERS*2+1, 1, 1,
597 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', NCLUSTERS*2+1, 1,
598 $ IWORK( INDIWRK+1+NCLUSTERS ),
599 $ NCLUSTERS*2+1, 1, 1, -1, -1, 0 )
601 DO 120 I = 1, NCLUSTERS
602.EQ..AND..NE.
IF( RESULT0 IWORK( INDIWRK+I )
603 $ IWORK( INDIWRK+NCLUSTERS+I ) ) THEN
605 $ WRITE( NOUT, FMT = 9984 )
610.NE.
IF( ICLUSTR( 1+IPREPAD+NCLUSTERS*2 )0 ) THEN
612 $ WRITE( NOUT, FMT = 9983 )
618 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, RESULT, 1, 1, 1,
628 EPSNORMA = PDLANSY( 'i
', UPLO, N, COPYA, IA, JA, DESCA,
632 IF( LSAME( JOBZ, 'v
' ) ) THEN
636 CALL PDFILLPAD( DESCA( CTXT_ ), SIZECHK, 1, WORK, SIZECHK,
637 $ IPREPAD, IPOSTPAD, 4.3D0 )
639 CALL PDSEPCHK( N, NZ, COPYA, IA, JA, DESCA,
640 $ MAX( ABSTOL+EPSNORMA, SAFMIN ), THRESH,
641 $ Z( 1+IPREPAD ), IA, JA, DESCZ,
642 $ A( 1+IPREPAD ), IA, JA, DESCA,
643 $ WNEW( 1+IPREPAD ), WORK( 1+IPREPAD ),
644 $ SIZECHK, TSTNRM, RES )
646 CALL PDCHEKPAD( DESCA( CTXT_ ), 'pdsepchk-work
', SIZECHK, 1,
647 $ WORK, SIZECHK, IPREPAD, IPOSTPAD, 4.3D0 )
654 CALL PDFILLPAD( DESCA( CTXT_ ), SIZEQTQ, 1, WORK, SIZEQTQ,
655 $ IPREPAD, IPOSTPAD, 4.3D0 )
658 CALL PDSEPQTQ( N, NZ, THRESH, Z( 1+IPREPAD ), IA, JA, DESCZ,
659 $ A( 1+IPREPAD ), IA, JA, DESCA,
660 $ IWORK( 1+IPREPAD+1 ), ICLUSTR( 1+IPREPAD ),
661 $ GAP( 1+IPREPAD ), WORK( IPREPAD+1 ), SIZEQTQ,
662 $ QTQNRM, INFO, RES )
664 CALL PDCHEKPAD( DESCA( CTXT_ ), 'pdsepqtq-work
', SIZEQTQ, 1,
665 $ WORK, SIZEQTQ, IPREPAD, IPOSTPAD, 4.3D0 )
672 $ WRITE( NOUT, FMT = 9998 )INFO
683 IF( LSAME( RANGE, 'v
' ) ) THEN
688 IF( LSAME( RANGE, 'a
' ) ) THEN
700 DO 140 MYIL = MINIL, MAXIL
705 MISSSMALLEST = .TRUE.
706.NOT.
IF( LSAME( RANGE, 'v.OR..EQ.
' ) ( MYIL1 ) )
707 $ MISSSMALLEST = .FALSE.
708.AND..LT.
IF( MISSSMALLEST ( WIN( MYIL-1 )VL+NORMWIN*
709 $ FIVE*THRESH*EPS ) )MISSSMALLEST = .FALSE.
711.NOT.
IF( LSAME( RANGE, 'v.OR..EQ.
' ) ( MYILMAXIL ) )
712 $ MISSLARGEST = .FALSE.
713.AND..GT.
IF( MISSLARGEST ( WIN( MYIL+M )VU-NORMWIN*FIVE*
714 $ THRESH*EPS ) )MISSLARGEST = .FALSE.
715.NOT.
IF( MISSSMALLEST ) THEN
716.NOT.
IF( MISSLARGEST ) THEN
723 ERROR = ABS( WIN( I+MYIL-1 )-WNEW( I+IPREPAD ) )
724 MAXERROR = MAX( MAXERROR, ERROR )
727 MINERROR = MIN( MAXERROR, MINERROR )
737 IF( LSAME( JOBZ, 'v.AND.
' ) LSAME( RANGE, 'a
' ) ) THEN
738.GT.
IF( MINERRORNORMWIN*FIVE*FIVE*THRESH*EPS ) THEN
740 $ WRITE( NOUT, FMT = 9997 )MINERROR, NORMWIN
744.GT.
IF( MINERRORNORMWIN*FIVE*THRESH*EPS ) THEN
746 $ WRITE( NOUT, FMT = 9997 )MINERROR, NORMWIN
754.NE..OR..NE..OR..NE..OR..NE.
IF( ILOLDIL IUOLDIU VLOLDVL VU
757 $ WRITE( NOUT, FMT = 9982 )
761 IF( LSAME( JOBZ, 'n.AND..NE.
' ) ( NZOLDNZ ) ) THEN
763 $ WRITE( NOUT, FMT = 9981 )
771 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, RESULT, 1, 1, 1, -1,
778 9999 FORMAT( 'pdsyevr returned info=
', I7 )
779 9998 FORMAT( 'pdsepqtq returned info=', i7 )
780 9997
FORMAT(
'PDSEPRSUBTST minerror =', d11.2,
' normwin=', d11.2 )
781 9996
FORMAT(
'PDSYEVR returned INFO=', i7,
782 $
' despite adequate workspace' )
783 9995
FORMAT( .NE..NE.
'ICLUSTR(1)0 but mod(INFO/2,2)1' )
784 9994
FORMAT(
'M not in the range 0 to N' )
785 9993
FORMAT(
'M not equal to N' )
786 9992
FORMAT(
'M not equal to IU-IL+1' )
787 9991
FORMAT(
'M not equal to NZ' )
788 9990
FORMAT(
'NZ > M' )
789 9989
FORMAT(
'NZ < M' )
790 9988
FORMAT(
'NZ not equal to M' )
791 9987
FORMAT(
'Different processes return different values for M' )
792 9986
FORMAT(
'Different processes return different eigenvalues' )
793 9985
FORMAT(
'Different processes return ',
794 $
'different numbers of clusters' )
795 9984
FORMAT(
'Different processes return different clusters' )
796 9983
FORMAT(
'ICLUSTR not zero terminated' )
797 9982
FORMAT(
'IL, IU, VL or VU altered by PDSYEVR'
798 9981
FORMAT(
'NZ altered by PDSYEVR with JOBZ=N' )