3 SUBROUTINE pcsepsubtst( WKNOWN, JOBZ, RANGE, UPLO, N, VL, VU, IL,
4 $ IU, THRESH, ABSTOL, A, COPYA, Z, IA, JA,
5 $ DESCA, WIN, WNEW, IFAIL, ICLUSTR, GAP,
6 $ IPREPAD, IPOSTPAD, WORK, LWORK, RWORK,
7 $ LRWORK, LWORK1, IWORK, LIWORK, RESULT,
8 $ TSTNRM, QTQNRM, NOUT )
17 CHARACTER JOBZ, RANGE, UPLO
18 INTEGER IA, IL, IPOSTPAD, IPREPAD, IU, JA, LIWORK,
19 $ LRWORK, LWORK, LWORK1, N, NOUT, RESULT
20 REAL ABSTOL, QTQNRM, THRESH, TSTNRM, VL, VU
23 INTEGER DESCA( * ), ICLUSTR( * ), IFAIL( * ),
25 REAL GAP( * ), RWORK( * ), WIN( * ), WNEW( * )
26 COMPLEX A( * ), COPYA( * ), WORK( * ), Z( * )
204 INTEGER , DLEN_, DTYPE_, CTXT_, M_, N_,
205 $ MB_, NB_, RSRC_, CSRC_, LLD_
207 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
208 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
209 REAL PADVAL, FIVE, NEGONE
210 PARAMETER ( PADVAL = 13.5285e+0, five = 5.0e+0,
213 PARAMETER ( CPADVAL = ( 13.989e+0, 1.93e+0 ) )
215 parameter( ipadval = 927 )
218 LOGICAL MISSLARGEST, MISSSMALLEST
219 INTEGER I, IAM, INDIWRK, INFO, ISIZEHEEVX, ISIZESUBTST,
220 $ isizetst, j, m, maxeigs, maxil, maxiu, maxsize,
221 $ minil, mq, mycol, myil, myrow, nclusters, np,
222 $ npcol, nprow, nq, nz, oldil, oldiu, oldnz, res,
223 $ rsizechk, rsizeheevx, rsizeqtq, rsizesubtst,
224 $ rsizetst, sizeheevx, sizemqrleft, sizemqrright,
225 $ sizeqrf, sizesubtst, sizetms, sizetst, valsize,
226 $ vecsize, sizeheevd, rsizeheevd, isizeheevd
227 REAL EPS, EPSNORMA, ERROR, MAXERROR, MAXVU,
228 $ MINERROR, MINVL, NORMWIN, OLDVL, OLDVU, ORFAC,
232 INTEGER DESCZ( DLEN_ ), DSEED( 4 ), ITMP( 2 )
238 REAL PCLANHE, PSLAMCH
239 EXTERNAL LSAME, NUMROC, PCLANHE, PSLAMCH
249 INTRINSIC abs,
max,
min, mod
253 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
255 CALL pclasizesep( desca, iprepad, ipostpad, sizemqrleft,
256 $ sizemqrright, sizeqrf, sizetms, rsizeqtq,
257 $ rsizechk, sizeheevx, rsizeheevx, isizeheevx,
258 $ sizeheevd, rsizeheevd, isizeheevd,
259 $ sizesubtst, rsizesubtst, isizesubtst, sizetst,
260 $ rsizetst, isizetst )
264 eps = pslamch( desca( ctxt_ ),
'Eps' )
265 safmin = pslamch( desca( ctxt_ ),
'Safe min' )
267 normwin = safmin / eps
269 $ normwin =
max( abs( win( 1 ) ), abs( win( n ) ), normwin )
281 rwork( i+iprepad ) = 14.3e+0
283 DO 20 i = 1, liwork, 1
284 iwork( i+iprepad ) = 14
286 DO 30 i = 1, lwork, 1
287 work( i+iprepad ) = ( 15.63e+0, 1.1e+0 )
291 wnew( i+iprepad ) = 3.14159e+0
294 iclustr( 1+iprepad ) = 139
296 IF( lsame( jobz,
'N' ) )
THEN
299 IF( lsame( range,
'A' ) )
THEN
301 ELSE IF( lsame( range,
'I' ) )
THEN
302 maxeigs = iu - il + 1
304 minvl = vl - normwin*five*eps - abstol
305 maxvu = vu + normwin*five*eps + abstol
309 IF( win( i ).LT.minvl )
311 IF( win( i ).LE.maxvu )
315 maxeigs = maxiu - minil + 1
320 CALL descinit( descz, desca( m_ ), desca( n_ ), desca( mb_ ),
321 $ desca( nb_ ), desca( rsrc_ ), desca( csrc_
322 $ desca( ctxt_ ), desca( lld_ ), info )
325 indiwrk = 1 + iprepad + nprow*npcol + 1
328 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
334 IF( myrow.GE.nprow .OR. myrow.LT.0 )
345 $ dseed, win, maxsize, vecsize, valsize )
347 np = numroc( n, desca( mb_ ), myrow, 0, nprow )
348 nq = numroc( n, desca( nb_ ), mycol, 0, npcol )
349 mq = numroc( maxeigs, desca( nb_ ), mycol, 0, npcol )
351 CALL clacpy(
'A', np, nq, copya, desca( lld_ ), a( 1+iprepad ),
354 CALL pcfillpad( desca( ctxt_ ), np, nq, a, desca( lld_ ), iprepad,
355 $ ipostpad, cpadval )
357 CALL pcfillpad( descz( ctxt_ ), np, mq, z, descz( lld_ ), iprepad,
358 $ ipostpad, cpadval+1.0e+0 )
360 CALL psfillpad( desca( ctxt_ ), n, 1, wnew, n, iprepad, ipostpad,
363 CALL psfillpad( desca( ctxt_ ), nprow*npcol, 1, gap, nprow*npcol,
364 $ iprepad, ipostpad, padval+3.0e+0 )
366 CALL psfillpad( desca( ctxt_ ), lwork1, 1, rwork, lwork1, iprepad,
367 $ ipostpad, padval+4.0e+0 )
369 CALL pifillpad( desca( ctxt_ ), liwork, 1, iwork, liwork, iprepad,
370 $ ipostpad, ipadval )
372 CALL pifillpad( desca( ctxt_ ), n, 1, ifail, n, iprepad, ipostpad,
375 CALL pifillpad( desca( ctxt_ ), 2*nprow*npcol, 1, iclustr,
376 $ 2*nprow*npcol, iprepad, ipostpad, ipadval )
378 CALL pcfillpad( desca( ctxt_ ), lwork, 1, work, lwork, iprepad,
379 $ ipostpad, cpadval+4.1e+0 )
385 DO 60 j = 1, maxeigs, 1
386 CALL pcelset( z( 1+iprepad ), i, j, desca,
387 $ ( 13.0e+0, 1.34e+0 ) )
396 CALL pcheevx( jobz, range, uplo, n, a( 1+iprepad ), ia, ja, desca,
397 $ vl, vu, il, iu, abstol, m, nz, wnew( 1+iprepad ),
398 $ orfac, z( 1+iprepad ), ia, ja, desca,
399 $ work( 1+iprepad ), sizeheevx, rwork( 1+iprepad ),
400 $ lwork1, iwork( 1+iprepad ), liwork,
401 $ ifail( 1+iprepad ), iclustr( 1+iprepad ),
402 $ gap( 1+iprepad ), info )
406 IF( thresh.LE.0 )
THEN
409 CALL pcchekpad( desca( ctxt_ ),
'PCHEEVX-A', np, nq, a,
410 $ desca( lld_ ), iprepad, ipostpad, cpadval )
412 CALL pcchekpad( descz( ctxt_ ),
'PCHEEVX-Z', np, mq, z,
413 $ descz( lld_ ), iprepad, ipostpad,
416 CALL pschekpad( desca( ctxt_ ),
'PCHEEVX-WNEW', n, 1, wnew, n,
417 $ iprepad, ipostpad, padval+2.0e+0 )
419 CALL pschekpad( desca( ctxt_ ),
'PCHEEVX-GAP', nprow*npcol, 1,
420 $ gap, nprow*npcol, iprepad, ipostpad,
423 CALL pschekpad( desca( ctxt_ ),
'PCHEEVX-rWORK', lwork1, 1,
424 $ rwork, lwork1, iprepad, ipostpad,
427 CALL pcchekpad( desca( ctxt_ ),
'PCHEEVX-WORK', lwork, 1, work,
428 $ lwork, iprepad, ipostpad, cpadval+4.1e+0 )
430 CALL pichekpad( desca( ctxt_ ),
'PCHEEVX-IWORK', liwork, 1,
431 $ iwork, liwork, iprepad, ipostpad, ipadval )
434 $ N, IPREPAD, IPOSTPAD, IPADVAL )
436 CALL PICHEKPAD( DESCA( CTXT_ ), 'pcheevx-iclustr
',
437 $ 2*NPROW*NPCOL, 1, ICLUSTR, 2*NPROW*NPCOL,
438 $ IPREPAD, IPOSTPAD, IPADVAL )
443 IF( LSAME( RANGE, 'a
' ) ) THEN
444 CALL PCLASIZEHEEVX( .TRUE., RANGE, N, DESCA, VL, VU, IL, IU,
445 $ DSEED, WNEW( 1+IPREPAD ), MAXSIZE,
458 CALL IGAMN2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP, 1, 1, 1,
460 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP( 2 ), 1, 1,
464.NE.
IF( ITMP( 1 )ITMP( 2 ) ) THEN
466 $ WRITE( NOUT, FMT = * )
467 $ 'different processes
return different info
'
469.EQ..OR..GT..OR..LT.
ELSE IF( MOD( INFO, 2 )1 INFO7 INFO0 )
472 $ WRITE( NOUT, FMT = 9999 )INFO
474.EQ..AND..GE.
ELSE IF( MOD( INFO / 2, 2 )1 LWORK1MAXSIZE ) THEN
476 $ WRITE( NOUT, FMT = 9996 )INFO
478.EQ..AND..GE.
ELSE IF( MOD( INFO / 4, 2 )1 LWORK1VECSIZE ) THEN
480 $ WRITE( NOUT, FMT = 9996 )INFO
485 IF( LSAME( JOBZ, 'v.AND..NE.
' ) ( ICLUSTR( 1+IPREPAD )
486.AND..NE.
$ 0 ) ( MOD( INFO / 2, 2 )1 ) ) THEN
488 $ WRITE( NOUT, FMT = 9995 )
494.LT..OR..GT.
IF( ( M0 ) ( MN ) ) THEN
496 $ WRITE( NOUT, FMT = 9994 )
498 ELSE IF( LSAME( RANGE, 'a.AND..NE.
' ) ( MN ) ) THEN
500 $ WRITE( NOUT, FMT = 9993 )
502 ELSE IF( LSAME( RANGE, 'i.AND..NE.
' ) ( MIU-IL+1 ) ) THEN
504 $ WRITE( NOUT, FMT = 9992 )
506 ELSE IF( LSAME( JOBZ, 'v.AND.
' )
507.NOT.
$ ( ( LSAME( RANGE, 'v.AND..NE.
' ) ) ) ( MNZ ) )
510 $ WRITE( NOUT, FMT = 9991 )
516 IF( LSAME( JOBZ, 'v
' ) ) THEN
517 IF( LSAME( RANGE, 'v
' ) ) THEN
520 $ WRITE( NOUT, FMT = 9990 )
523.LT..AND..NE.
IF( NZM MOD( INFO / 4, 2 )1 ) THEN
525 $ WRITE( NOUT, FMT = 9989 )
531 $ WRITE( NOUT, FMT = 9988 )
536.EQ.
IF( RESULT0 ) THEN
543 CALL IGAMN2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP, 1, 1, 1,
545 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, ITMP( 2 ), 1,
548.NE.
IF( ITMP( 1 )ITMP( 2 ) ) THEN
550 $ WRITE( NOUT, FMT = 9987 )
557 RWORK( I ) = WNEW( I+IPREPAD )
558 RWORK( I+M ) = WNEW( I+IPREPAD )
561 CALL SGAMN2D( DESCA( CTXT_ ), 'a',
' ', m, 1, rwork, m,
563 CALL sgamx2d( desca( ctxt_ ),
'a',
' ', m, 1,
564 $ rwork( 1+m ), m, 1, 1, -1, -1, 0 )
568 IF( result.EQ.0 .AND. ( abs( rwork( i )-rwork( m+
569 $ i ) ).GT.five*eps*abs( rwork( i ) ) ) )
THEN
571 $
WRITE( nout, fmt = 9986 )
580 IF( lsame( jobz,
'V' ) )
THEN
582 DO 100 i = 0, nprow*npcol - 1
583 IF( iclustr( 1+iprepad+2*i ).EQ.0 )
585 nclusters = nclusters + 1
588 itmp( 1 ) = nclusters
589 itmp( 2 ) = nclusters
591 CALL igamn2d( desca( ctxt_ ),
'a',
' ', 1, 1, itmp, 1, 1, 1,
593 CALL igamx2d( desca( ctxt_ ),
'a',
' ', 1, 1, itmp( 2 ), 1,
596 IF( itmp( 1 ).NE.itmp( 2 ) )
THEN
598 $
WRITE( nout, fmt = 9985 )
604 DO 120 i = 1, nclusters
605 iwork( indiwrk+i ) = iclustr( i+iprepad )
606 iwork( indiwrk+i+nclusters ) = iclustr( i+iprepad )
608 CALL igamn2d( desca( ctxt_ ),
'a',
' ', nclusters*2+1, 1,
609 $ iwork( indiwrk+1 ), nclusters*2+1, 1, 1,
611 CALL igamx2d( desca( ctxt_ ),
'a',
' ', nclusters*2+1, 1,
612 $ iwork( indiwrk+1+nclusters ),
613 $ nclusters*2+1, 1, 1, -1, -1, 0 )
616 DO 130 i = 1, nclusters
617 IF( result.EQ.0 .AND. iwork( indiwrk+i ).NE.
618 $ iwork( indiwrk+nclusters+i ) )
THEN
620 $
WRITE( nout, fmt = 9984 )
625 IF( iclustr( 1+iprepad+nclusters*2 ).NE.0 )
THEN
627 $
WRITE( nout, fmt = 9983 )
634 CALL igamx2d( desca( ctxt_ ),
'a',
' ', 1, 1, result,
644 epsnorma = pclanhe(
'I', uplo, n, copya, ia, ja, desca,
658 IF( lsame( jobz,
'V' ) )
THEN
662 CALL psfillpad( desca( ctxt_ ), rsizechk, 1, rwork,
663 $ rsizechk, iprepad, ipostpad, 4.3e+0 )
665 CALL pcsepchk( n, nz, copya, ia, ja, desca,
666 $
max( abstol+epsnorma, safmin ), thresh,
667 $ z( 1+iprepad ), ia, ja, descz,
668 $ a( 1+iprepad ), ia, ja, desca,
669 $ wnew( 1+iprepad ), rwork( 1+iprepad ),
670 $ rsizechk, tstnrm, res )
673 $ 1, RWORK, RSIZECHK, IPREPAD, IPOSTPAD,
681 CALL PSFILLPAD( DESCA( CTXT_ ), RSIZEQTQ, 1, RWORK,
682 $ RSIZEQTQ, IPREPAD, IPOSTPAD, 4.3E+0 )
685 CALL PCSEPQTQ( N, NZ, THRESH, Z( 1+IPREPAD ), IA, JA, DESCZ,
686 $ A( 1+IPREPAD ), IA, JA, DESCA,
687 $ IWORK( 1+IPREPAD+1 ), ICLUSTR( 1+IPREPAD ),
688 $ GAP( 1+IPREPAD ), RWORK( IPREPAD+1 ),
689 $ RSIZEQTQ, QTQNRM, INFO, RES )
691 CALL PSCHEKPAD( DESCA( CTXT_ ), 'pcsepqtq-rwork
', RSIZEQTQ,
692 $ 1, RWORK, RSIZEQTQ, IPREPAD, IPOSTPAD,
700 $ WRITE( NOUT, FMT = 9998 )INFO
713 IF( LSAME( RANGE, 'v
' ) ) THEN
718 IF( LSAME( RANGE, 'a
' ) ) THEN
730 DO 150 MYIL = MINIL, MAXIL
735 MISSSMALLEST = .TRUE.
736.NOT.
IF( LSAME( RANGE, 'v.OR..EQ.
' ) ( MYIL1 ) )
737 $ MISSSMALLEST = .FALSE.
738.AND..LT.
IF( MISSSMALLEST ( WIN( MYIL-1 )VL+NORMWIN*
739 $ FIVE*THRESH*EPS ) )MISSSMALLEST = .FALSE.
741.NOT.
IF( LSAME( RANGE, 'v.OR..EQ.
' ) ( MYILMAXIL ) )
742 $ MISSLARGEST = .FALSE.
743.AND..GT.
IF( MISSLARGEST ( WIN( MYIL+M )VU-NORMWIN*FIVE*
744 $ THRESH*EPS ) )MISSLARGEST = .FALSE.
745.NOT.
IF( MISSSMALLEST ) THEN
746.NOT.
IF( MISSLARGEST ) THEN
751 ERROR = ABS( WIN( I+MYIL-1 )-WNEW( I+IPREPAD ) )
752 MAXERROR = MAX( MAXERROR, ERROR )
755 MINERROR = MIN( MAXERROR, MINERROR )
766 IF( LSAME( JOBZ, 'v.AND.
' ) LSAME( RANGE, 'a
' ) ) THEN
767.GT.
IF( MINERRORNORMWIN*FIVE*FIVE*THRESH*EPS ) THEN
769 $ WRITE( NOUT, FMT = 9997 )MINERROR, NORMWIN
773.GT.
IF( MINERRORNORMWIN*FIVE*THRESH*EPS ) THEN
775 $ WRITE( NOUT, FMT = 9997 )MINERROR, NORMWIN
784.NE..OR..NE..OR..NE..OR..NE.
IF( ILOLDIL IUOLDIU VLOLDVL VU
787 $ WRITE( NOUT, FMT = 9982 )
791 IF( LSAME( JOBZ, 'n.AND..NE.
' ) ( NZOLDNZ ) ) THEN
793 $ WRITE( NOUT, FMT = 9981 )
801 CALL IGAMX2D( DESCA( CTXT_ ), 'a
', ' ', 1, 1, RESULT, 1, 1, 1, -1,
809 9999 FORMAT( 'pcheevx returned info=
', I7 )
810 9998 FORMAT( 'pcsepqtq returned info=
', I7 )
811 9997 FORMAT( 'pcsepsubtst minerror =
', D11.2, ' normwin=
', D11.2 )
812 9996 FORMAT( 'pcheevx returned info=
', I7,
813 $ ' despite adequate workspace
' )
814 9995 FORMAT( 'iclustr(1).NE.0 but mod(info/2,2).NE.1
' )
815 9994 FORMAT( 'm not in
the range 0 to n
' )
816 9993 FORMAT( 'm not equal to n
' )
817 9992 FORMAT( 'm not equal to iu-il+1
' )
818 9991 FORMAT( 'm not equal to nz
' )
819 9990 FORMAT( 'nz > m
' )
820 9989 FORMAT( 'nz < m
' )
821 9988 FORMAT( 'nz not equal to m
' )
822 9987 FORMAT( 'different processes
return different values
for m
' )
823 9986 FORMAT( 'different processes
return different eigenvalues
' )
824 9985 FORMAT( 'different processes
return ',
825 $ 'different numbers of clusters
' )
826 9984 FORMAT( 'different processes
return different clusters
' )
827 9983 FORMAT( 'iclustr not zero terminated
' )
828 9982 FORMAT( 'il, iu, vl or vu altered by
pcheevx' )
829 9981 FORMAT( 'nz altered by
pcheevx with jobz=n
' )