3 SUBROUTINE pdgsepsubtst( WKNOWN, IBTYPE, JOBZ, RANGE, UPLO, N, VL,
4 $ VU, IL, IU, THRESH, ABSTOL, A, COPYA, B,
5 $ COPYB, Z, IA, JA, DESCA, WIN, WNEW,
6 $ IFAIL, ICLUSTR, GAP, IPREPAD, IPOSTPAD,
7 $ WORK, LWORK, LWORK1, IWORK, LIWORK,
8 $ RESULT, TSTNRM, QTQNRM, NOUT )
17 CHARACTER JOBZ, RANGE, UPLO
18 INTEGER IA, IBTYPE, IL, IPOSTPAD, IPREPAD, IU, JA,
19 $ LIWORK, LWORK, , N, NOUT, RESULT
20 DOUBLE PRECISION ABSTOL, QTQNRM, THRESH, TSTNRM, VL, VU
23 INTEGER DESCA( * ), ICLUSTR( * ), ( * ),
25 DOUBLE PRECISION ( * ), B( * ), COPYA( * ), COPYB( * ),
26 $ GAP( * ), WIN( * ), WNEW( * ), WORK( * ),
216 INTEGER BLOCK_CYCLIC_2D, DLEN_, , CTXT_, M_, N_,
217 $ MB_, NB_, RSRC_, CSRC_, LLD_
218 PARAMETER ( BLOCK_CYCLIC_2D = 1, dlen_ = 9, dtype_ = 1,
219 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
220 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
221 DOUBLE PRECISION PADVAL, FIVE, NEGONE
225 PARAMETER ( IPADVAL = 927 )
228 LOGICAL MISSLARGEST, MISSSMALLEST
229 INTEGER I, IAM, INDIWRK, INFO, ISIZESUBTST, ISIZESYEVX,
230 $ isizetst, j, m, maxeigs, maxil, maxiu, maxsize,
231 $ minil, mq, mycol, myil, myrow, nclusters, np,
232 $ npcol, nprow, nq, nz, oldil, oldiu, oldnz, res,
233 $ sizechk, sizemqrleft, sizemqrright, sizeqrf,
234 $ sizeqtq, sizesubtst, sizesyevx, sizetms,
235 $ sizetst, valsize, vecsize
236 DOUBLE PRECISION EPS, ERROR, MAXERROR, MAXVU, MINERROR, ,
237 $ NORMWIN, OLDVL, OLDVU, ORFAC, SAFMIN
240 INTEGER DESCZ( DLEN_ ), DSEED( 4 ), ITMP( 2 )
246 DOUBLE PRECISION PDLAMCH
247 EXTERNAL LSAME, NUMROC, PDLAMCH
257 INTRINSIC abs,
max,
min, mod
261 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
263 CALL pdlasizegsep( desca, iprepad, ipostpad, sizemqrleft,
264 $ sizemqrright, sizeqrf, sizetms, sizeqtq,
265 $ sizechk, sizesyevx, isizesyevx, sizesubtst,
266 $ isizesubtst, sizetst, isizetst )
270 eps = pdlamch( desca( ctxt_ ),
'Eps' )
271 safmin = pdlamch( desca( ctxt_ ),
'Safe min' )
273 normwin = safmin / eps
275 $ normwin =
max( abs( win( 1 ) ), abs( win( n ) ), normwin )
286 DO 10 i = 1, lwork1, 1
287 work( i+iprepad ) = 14.3d+0
289 DO 20 i = 1, liwork, 1
290 iwork( i+iprepad ) = 14
294 wnew( i+iprepad ) = 3.14159d+0
297 iclustr( 1+iprepad ) = 139
299 IF( lsame( jobz,
'N' ) )
THEN
302 IF( lsame( range,
'A' ) )
THEN
304 ELSE IF( lsame( range,
'I' ) )
THEN
305 maxeigs = iu - il + 1
307 minvl = vl - normwin*five*eps - abstol
308 maxvu = vu + normwin*five*eps + abstol
312 IF( win( i ).LT.minvl )
314 IF( win( i ).LE.maxvu )
318 maxeigs = maxiu - minil + 1
323 CALL descinit( descz, desca( m_ ), desca( n_ ), desca( mb_ ),
324 $ desca( nb_ ), desca( rsrc_ ), desca( csrc_ ),
325 $ desca( ctxt_ ), desca( lld_ ), info )
328 indiwrk = 1 + iprepad + nprow*npcol + 1
331 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
337 IF( myrow.GE.nprow .OR. myrow.LT.0 )
348 $ dseed, win, maxsize, vecsize
350 np = numroc( n, desca( mb_ ), myrow, 0, nprow )
351 nq = numroc( n, desca( nb_ ), mycol, 0, npcol )
352 mq = numroc( maxeigs, desca( nb_ ), mycol, 0, npcol )
354 CALL dlacpy(
'A', np, nq, copya, desca( lld_ ), a( 1+iprepad ),
357 CALL dlacpy(
'A', np, nq, copyb, desca( lld_ ), b( 1+iprepad ),
360 CALL pdfillpad( desca( ctxt_ ), np, nq, b, desca( lld_ ), iprepad,
361 $ ipostpad, padval+1.0d+2 )
363 CALL pdfillpad( desca( ctxt_ ), np, nq, a, desca( lld_ ), iprepad,
366 CALL pdfillpad( descz( ctxt_ ), np, mq, z, descz( lld_ ), iprepad,
367 $ ipostpad, padval+1.0d+0 )
369 CALL pdfillpad( desca( ctxt_ ), n, 1, wnew, n, iprepad, ipostpad,
372 CALL pdfillpad( desca( ctxt_ ), nprow*npcol, 1, gap, nprow*npcol,
373 $ iprepad, ipostpad, padval+3.0d+0 )
375 CALL pdfillpad( desca( ctxt_ ), lwork1, 1, work, lwork1, iprepad,
376 $ ipostpad, padval+4.0d+0 )
378 CALL pifillpad( desca( ctxt_ ), liwork, 1, iwork, liwork, iprepad,
379 $ ipostpad, ipadval )
381 CALL pifillpad( desca( ctxt_ ), n, 1, ifail, n, iprepad, ipostpad,
384 CALL pifillpad( desca( ctxt_ ), 2*nprow*npcol, 1, iclustr,
385 $ 2*nprow*npcol, iprepad, ipostpad, ipadval )
391 DO 50 j = 1, maxeigs, 1
392 CALL pdelset( z( 1+iprepad ), i, j, desca, 13.0d+0 )
401 CALL pdsygvx( ibtype, jobz, range, uplo, n, a( 1+iprepad ), ia,
402 $ ja, desca, b( 1+iprepad ), ia, ja, desca, vl, vu,
403 $ il, iu, abstol, m, nz, wnew( 1+iprepad ), orfac,
404 $ z( 1+iprepad ), ia, ja, desca, work( 1+iprepad ),
405 $ lwork1, iwork( 1+iprepad ), liwork,
406 $ ifail( 1+iprepad ), iclustr( 1+iprepad ),
407 $ gap( 1+iprepad ), info )
411 IF( thresh.LE.0 )
THEN
414 CALL pdchekpad( desca( ctxt_ ),
'PDSYGVX-B', np, nq, b,
415 $ desca( lld_ ), iprepad, ipostpad,
418 CALL pdchekpad( desca( ctxt_ ),
'PDSYGVX-A', np, nq, a,
419 $ desca( lld_ ), iprepad, ipostpad, padval )
421 CALL pdchekpad( descz( ctxt_ ),
'PDSYGVX-Z', np, mq, z,
422 $ descz( lld_ ), iprepad, ipostpad,
425 CALL pdchekpad( desca( ctxt_ ),
'PDSYGVX-WNEW', n, 1, wnew, n,
426 $ iprepad, ipostpad, padval+2.0d+0 )
428 CALL pdchekpad( desca( ctxt_ ),
'PDSYGVX-GAP', nprow*npcol, 1,
429 $ gap, nprow*npcol, iprepad, ipostpad,
432 CALL pdchekpad( desca( ctxt_ ),
'PDSYGVX-WORK', lwork1, 1,
433 $ work, lwork1, iprepad, ipostpad,
436 CALL pichekpad( desca( ctxt_ ),
'PDSYGVX-IWORK', liwork, 1,
437 $ iwork, liwork, iprepad, ipostpad, ipadval )
439 CALL pichekpad( desca( ctxt_ ),
'PDSYGVX-IFAIL', n, 1, ifail,
440 $ n, iprepad, ipostpad, ipadval )
442 CALL pichekpad( desca( ctxt_ ),
'PDSYGVX-ICLUSTR',
443 $ 2*nprow*npcol, 1, iclustr, 2*nprow*npcol,
444 $ iprepad, ipostpad, ipadval )
449 IF( lsame( range,
'A' ) )
THEN
451 $ dseed, wnew( 1+iprepad ), maxsize,
464 CALL igamn2d( desca( ctxt_ ),
'a',
' ', 1, 1, itmp, 1, 1, 1,
466 CALL igamx2d( desca( ctxt_ ),
'a',
' ', 1, 1, itmp( 2 ), 1, 1,
470 IF( itmp( 1 ).NE.itmp( 2 ) )
THEN
472 $
WRITE( nout, fmt = * )
473 $
'Different processes return different INFO'
475 ELSE IF( mod( info, 2 ).EQ.1 .OR. info.GT.7 .OR. info.LT.0 )
478 $
WRITE( nout, fmt = 9999 )info
480 ELSE IF( mod( info / 2, 2 ).EQ.1 .AND. lwork1.GE.maxsize )
THEN
482 $
WRITE( nout, fmt = 9996 )info
484 ELSE IF( mod( info / 4, 2 ).EQ.1 .AND. lwork1.GE.vecsize )
THEN
486 $
WRITE( nout, fmt = 9996 )info
491 IF( lsame( jobz,
'V' ) .AND. ( iclustr( 1+iprepad ).NE.
492 $ 0 ) .AND. ( mod( info / 2, 2 ).NE.1 ) )
THEN
494 $
WRITE( nout, fmt = 9995 )
500 IF( ( m.LT.0 ) .OR. ( m.GT.n ) )
THEN
502 $
WRITE( nout, fmt = 9994 )
504 ELSE IF( lsame( range, 'a.AND..NE.
' ) ( MN ) ) THEN
506 $ WRITE( NOUT, FMT = 9993 )
508 ELSE IF( LSAME( RANGE, 'i.AND..NE.
' ) ( MIU-IL+1 ) ) THEN
510 $ WRITE( NOUT, FMT = 9992 )
512 ELSE IF( LSAME( JOBZ, 'v.AND.
' )
513.NOT.
$ ( ( LSAME( RANGE, 'v.AND..NE.
' ) ) ) ( MNZ ) )
516 $ WRITE( NOUT, FMT = 9991 )
522 IF( LSAME( JOBZ, 'v
' ) ) THEN
523 IF( LSAME( RANGE, 'v
' ) ) THEN
526 $ WRITE( NOUT, FMT = 9990 )
529.LT..AND..NE.
IF( NZM MOD( INFO / 4, 2 )1 ) THEN
531 $ WRITE( NOUT, FMT = 9989 )
537 $ WRITE( NOUT, FMT = 9988 )
542.EQ.
IF( RESULT0 ) THEN
549 CALL IGAMN2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP, 1, 1, 1,
551 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP( 2 ), 1,
554.NE.
IF( ITMP( 1 )ITMP( 2 ) ) THEN
556 $ WRITE( NOUT, FMT = 9987 )
563 WORK( I ) = WNEW( I+IPREPAD )
564 WORK( I+M ) = WNEW( I+IPREPAD )
567 CALL DGAMN2D( DESCA( CTXT_ ), 'a
', ' ', M, 1, WORK, M, 1,
569 CALL DGAMX2D( DESCA( CTXT_ ), 'a
', ' ', M, 1,
570 $ WORK( 1+M ), M, 1, 1, -1, -1, 0 )
574.EQ..AND.
IF( RESULT0 ( ABS( WORK( I )-WORK( M+
575.GT.
$ I ) )FIVE*EPS*ABS( WORK( I ) ) ) ) THEN
577 $ WRITE( NOUT, FMT = 9986 )
586 IF( LSAME( JOBZ, 'v
' ) ) THEN
588 DO 90 I = 0, NPROW*NPCOL - 1
589.EQ.
IF( ICLUSTR( 1+IPREPAD+2*I )0 )
591 NCLUSTERS = NCLUSTERS + 1
594 ITMP( 1 ) = NCLUSTERS
595 ITMP( 2 ) = NCLUSTERS
597 CALL IGAMN2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP, 1, 1, 1,
599 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP( 2 ), 1,
602.NE.
IF( ITMP( 1 )ITMP( 2 ) ) THEN
604 $ WRITE( NOUT, FMT = 9985 )
610 DO 110 I = 1, NCLUSTERS
611 IWORK( INDIWRK+I ) = ICLUSTR( I+IPREPAD )
612 IWORK( INDIWRK+I+NCLUSTERS ) = ICLUSTR( I+IPREPAD )
614 CALL IGAMN2D( DESCA( CTXT_ ), 'a
', ' ', NCLUSTERS*2+1, 1,
615 $ IWORK( INDIWRK+1 ), NCLUSTERS*2+1, 1, 1,
617 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', NCLUSTERS*2+1, 1,
618 $ IWORK( INDIWRK+1+NCLUSTERS ),
619 $ NCLUSTERS*2+1, 1, 1, -1, -1, 0 )
622 DO 120 I = 1, NCLUSTERS
623.EQ..AND..NE.
IF( RESULT0 IWORK( INDIWRK+I )
624 $ IWORK( INDIWRK+NCLUSTERS+I ) ) THEN
626 $ WRITE( NOUT, FMT = 9984 )
631.NE.
IF( ICLUSTR( 1+IPREPAD+NCLUSTERS*2 )0 ) THEN
633 $ WRITE( NOUT, FMT = 9983 )
640 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, RESULT, 1, 1, 1,
656 IF( LSAME( JOBZ, 'v
' ) ) THEN
660 CALL PDFILLPAD( DESCA( CTXT_ ), SIZECHK, 1, WORK, SIZECHK,
661 $ IPREPAD, IPOSTPAD, 4.3D+0 )
663 CALL PDGSEPCHK( IBTYPE, N, NZ, COPYA, IA, JA, DESCA, COPYB,
664 $ IA, JA, DESCA, THRESH, Z( 1+IPREPAD ), IA,
665 $ JA, DESCZ, A( 1+IPREPAD ), IA, JA, DESCA,
666 $ WNEW( 1+IPREPAD ), WORK( 1+IPREPAD ),
667 $ SIZECHK, TSTNRM, RES )
669 CALL PDCHEKPAD( DESCA( CTXT_ ), 'pdgsepchk-work
', SIZECHK,
670 $ 1, WORK, SIZECHK, IPREPAD, IPOSTPAD,
685 IF( LSAME( RANGE, 'v
' ) ) THEN
690 IF( LSAME( RANGE, 'a
' ) ) THEN
702 DO 140 MYIL = MINIL, MAXIL
707 MISSSMALLEST = .TRUE.
708.NOT.
IF( LSAME( RANGE, 'v.OR..EQ.
' ) ( MYIL1 ) )
709 $ MISSSMALLEST = .FALSE.
710.AND..LT.
IF( MISSSMALLEST ( WIN( MYIL-1 )VL+NORMWIN*
711 $ FIVE*THRESH*EPS ) )MISSSMALLEST = .FALSE.
713.NOT.
IF( LSAME( RANGE, 'v.OR..EQ.
' ) ( MYILMAXIL ) )
714 $ MISSLARGEST = .FALSE.
715.AND..GT.
IF( MISSLARGEST ( WIN( MYIL+M )VU-NORMWIN*FIVE*
716 $ THRESH*EPS ) )MISSLARGEST = .FALSE.
717.NOT.
IF( MISSSMALLEST ) THEN
718.NOT.
IF( MISSLARGEST ) THEN
723 ERROR = ABS( WIN( I+MYIL-1 )-WNEW( I+IPREPAD ) )
724 MAXERROR = MAX( MAXERROR, ERROR )
727 MINERROR = MIN( MAXERROR, MINERROR )
738 IF( LSAME( JOBZ, 'v.AND.
' ) LSAME( RANGE, 'a
' ) ) THEN
739.GT.
IF( MINERRORNORMWIN*FIVE*FIVE*THRESH*EPS ) THEN
741 $ WRITE( NOUT, FMT = 9997 )MINERROR, NORMWIN
745.GT.
IF( MINERRORNORMWIN*FIVE*THRESH*EPS ) THEN
747 $ WRITE( NOUT, FMT = 9997 )MINERROR, NORMWIN
756.NE..OR..NE..OR..NE..OR..NE.
IF( ILOLDIL IUOLDIU VLOLDVL VU
759 $ WRITE( NOUT, FMT = 9982 )
763 IF( LSAME( JOBZ, 'n.AND..NE.
' ) ( NZOLDNZ ) ) THEN
765 $ WRITE( NOUT, FMT = 9981 )
773 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, RESULT, 1, 1, 1, -1,
781 9999 FORMAT( 'pdsygvx returned info=
', I7 )
782 9998 FORMAT( 'pdsepqtq returned info=
', I7 )
783 9997 FORMAT( 'pdgsepsubtst minerror =
', D11.2, ' normwin=
', D11.2 )
784 9996 FORMAT( 'pdsygvx returned info=
', I7,
785 $ ' despite adequate workspace
' )
786 9995 FORMAT( 'iclustr(1).NE.0 but mod(info/2,2).NE.1
' )
787 9994 FORMAT( 'm not in
the range 0 to n
' )
788 9993 FORMAT( 'm not equal to n
' )
789 9992 FORMAT( 'm not equal to iu-il+1
' )
790 9991 FORMAT( 'm not equal to nz
' )
791 9990 FORMAT( 'nz > m
' )
792 9989 FORMAT( 'nz < m
' )
793 9988 FORMAT( 'nz not equal to m
' )
794 9987 FORMAT( 'different processes
return different values
for m
' )
795 9986 FORMAT( 'different processes
return different eigenvalues
' )
796 9985 FORMAT( 'different processes
return ',
797 $ 'different numbers of clusters
' )
798 9984 FORMAT( 'different processes
return different clusters
' )
799 9983 FORMAT( 'iclustr not zero terminated
' )
800 9982 FORMAT( 'il, iu, vl or vu altered by
pdsygvx' )
801 9981 FORMAT( 'nz altered by
pdsygvx with jobz=n
' )