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, LWORK1, N, NOUT, RESULT
20 DOUBLE PRECISION ABSTOL, QTQNRM, THRESH, TSTNRM, VL, VU
23 INTEGER DESCA( * ), ICLUSTR( * ), IFAIL( * ),
25 DOUBLE PRECISION A( * ), B( * ), COPYA( * ), COPYB( * ),
26 $ GAP( * ), WIN( * ), WNEW( * ), WORK( * ),
216 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, 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
222 PARAMETER ( PADVAL = 13.5285d+0, five = 5.0d+0,
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, MINVL,
237 $ NORMWIN, OLDVL, OLDVU, ORFAC, SAFMIN
240 INTEGER DESCZ( DLEN_ ), DSEED( 4 ), ITMP( 2 )
246 DOUBLE PRECISION PDLAMCH
247 EXTERNAL LSAME, NUMROC, PDLAMCH
250 EXTERNAL blacs_gridinfo,
descinit, dgamn2d, dgamx2d,
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 )
327 CALL blacs_gridinfo( desca( ctxt_ ), nprow, npcol, myrow, mycol )
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, valsize )
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. ( m.NE.n ) )
THEN
506 $
WRITE( nout, fmt = 9993 )
508 ELSE IF( lsame( range,
'I' ) .AND. ( m.NE.iu-il+1 ) )
THEN
510 $
WRITE( nout, fmt = 9992 )
512 ELSE IF( lsame( jobz,
'V' ) .AND.
513 $ ( .NOT.( lsame( range,
'V' ) ) ) .AND. ( m.NE.nz ) )
516 $
WRITE( nout, fmt = 9991 )
522 IF( lsame( jobz,
'V' ) )
THEN
523 IF( lsame( range,
'V' ) )
THEN
526 $
WRITE( nout, fmt = 9990 )
529 IF( nz.LT.m .AND. mod( info / 4, 2 ).NE.1 )
THEN
531 $
WRITE( nout, fmt = 9989 )
537 $
WRITE( nout, fmt = 9988 )
542 IF( result.EQ.0 )
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 IF( itmp( 1 ).NE.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 IF( result.EQ.0 .AND. ( abs( work( i )-work( m+
575 $ i ) ).GT.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 IF( iclustr( 1+iprepad+2*i ).EQ.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 IF( itmp( 1 ).NE.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 IF( result.EQ.0 .AND. iwork( indiwrk+i ).NE.
624 $ iwork( indiwrk+nclusters+i ) )
THEN
626 $
WRITE( nout, fmt = 9984 )
631 IF( iclustr( 1+iprepad+nclusters*2 ).NE.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 IF( .NOT.lsame( range,
'V' ) .OR. ( myil.EQ.1 ) )
709 $ misssmallest = .false.
710 IF( misssmallest .AND. ( win( myil-1 ).LT.vl+normwin*
711 $ five*thresh*eps ) )misssmallest = .false.
713 IF( .NOT.lsame( range,
'V' ) .OR. ( myil.EQ.maxil ) )
714 $ misslargest = .false.
715 IF( misslargest .AND. ( win( myil+m ).GT.vu-normwin*five*
716 $ thresh*eps ) )misslargest = .false.
717 IF( .NOT.misssmallest )
THEN
718 IF( .NOT.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 IF( minerror.GT.normwin*five*five*thresh*eps )
THEN
741 $
WRITE( nout, fmt = 9997 )minerror, normwin
745 IF( minerror.GT.normwin*five*thresh*eps )
THEN
747 $
WRITE( nout, fmt = 9997 )minerror, normwin
756 IF( il.NE.oldil .OR. iu.NE.oldiu .OR. vl.NE.oldvl .OR. vu.NE.
759 $
WRITE( nout, fmt = 9982 )
763 IF( lsame( jobz,
'N' ) .AND. ( nz.NE.oldnz ) )
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( .NE..NE.
'ICLUSTR(1)0 but mod(INFO/2,2)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' )