Skip to content

Commit cd7523d

Browse files
committed
handle corner case of lwork in evr/evr_2stage and fix output format in chkxer
1 parent 9dc2480 commit cd7523d

File tree

13 files changed

+117
-65
lines changed

13 files changed

+117
-65
lines changed

SRC/cheevr.f

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@
272272
*> \param[in] LWORK
273273
*> \verbatim
274274
*> LWORK is INTEGER
275-
*> The length of the array WORK. LWORK >= max(1,2*N).
275+
*> The length of the array WORK.
276+
*> If N <= 1, LWORK >= 1, else LWORK >= 2*N.
276277
*> For optimal efficiency, LWORK >= (NB+1)*N,
277278
*> where NB is the max of the blocksize for CHETRD and for
278279
*> CUNMTR as returned by ILAENV.
@@ -294,7 +295,8 @@
294295
*> \param[in] LRWORK
295296
*> \verbatim
296297
*> LRWORK is INTEGER
297-
*> The length of the array RWORK. LRWORK >= max(1,24*N).
298+
*> The length of the array RWORK.
299+
*> If N <= 1, LRWORK >= 1, else LRWORK >= 24*N.
298300
*>
299301
*> If LRWORK = -1, then a workspace query is assumed; the
300302
*> routine only calculates the optimal sizes of the WORK, RWORK
@@ -313,7 +315,8 @@
313315
*> \param[in] LIWORK
314316
*> \verbatim
315317
*> LIWORK is INTEGER
316-
*> The dimension of the array IWORK. LIWORK >= max(1,10*N).
318+
*> The dimension of the array IWORK.
319+
*> If N <= 1, LIWORK >= 1, else LIWORK >= 10*N.
317320
*>
318321
*> If LIWORK = -1, then a workspace query is assumed; the
319322
*> routine only calculates the optimal sizes of the WORK, RWORK
@@ -417,9 +420,15 @@ SUBROUTINE CHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
417420
LQUERY = ( ( LWORK.EQ.-1 ) .OR. ( LRWORK.EQ.-1 ) .OR.
418421
$ ( LIWORK.EQ.-1 ) )
419422
*
420-
LRWMIN = MAX( 1, 24*N )
421-
LIWMIN = MAX( 1, 10*N )
422-
LWMIN = MAX( 1, 2*N )
423+
IF( N.LE.1 ) THEN
424+
LWMIN = 1
425+
LRWMIN = 1
426+
LIWMIN = 1
427+
ELSE
428+
LWMIN = 2*N
429+
LRWMIN = 24*N
430+
LIWMIN = 10*N
431+
END IF
423432
*
424433
INFO = 0
425434
IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
@@ -454,8 +463,8 @@ SUBROUTINE CHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
454463
NB = ILAENV( 1, 'CHETRD', UPLO, N, -1, -1, -1 )
455464
NB = MAX( NB, ILAENV( 1, 'CUNMTR', UPLO, N, -1, -1, -1 ) )
456465
LWKOPT = MAX( ( NB+1 )*N, LWMIN )
457-
WORK( 1 ) = SROUNDUP_LWORK(LWKOPT)
458-
RWORK( 1 ) = LRWMIN
466+
WORK( 1 ) = SROUNDUP_LWORK( LWKOPT )
467+
RWORK( 1 ) = SROUNDUP_LWORK( LRWMIN )
459468
IWORK( 1 ) = LIWMIN
460469
*
461470
IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
@@ -483,7 +492,7 @@ SUBROUTINE CHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
483492
END IF
484493
*
485494
IF( N.EQ.1 ) THEN
486-
WORK( 1 ) = 2
495+
WORK( 1 ) = 1
487496
IF( ALLEIG .OR. INDEIG ) THEN
488497
M = 1
489498
W( 1 ) = REAL( A( 1, 1 ) )
@@ -710,8 +719,8 @@ SUBROUTINE CHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
710719
*
711720
* Set WORK(1) to optimal workspace size.
712721
*
713-
WORK( 1 ) = SROUNDUP_LWORK(LWKOPT)
714-
RWORK( 1 ) = LRWMIN
722+
WORK( 1 ) = SROUNDUP_LWORK( LWKOPT )
723+
RWORK( 1 ) = SROUNDUP_LWORK( LRWMIN )
715724
IWORK( 1 ) = LIWMIN
716725
*
717726
RETURN

SRC/cheevr_2stage.f

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@
280280
*> \verbatim
281281
*> LWORK is INTEGER
282282
*> The dimension of the array WORK.
283+
*> If N <= 1, LWORK must be at least 1.
283284
*> If JOBZ = 'N' and N > 1, LWORK must be queried.
284285
*> LWORK = MAX(1, 26*N, dimension) where
285286
*> dimension = max(stage1,stage2) + (KD+1)*N + N
@@ -310,7 +311,8 @@
310311
*> \param[in] LRWORK
311312
*> \verbatim
312313
*> LRWORK is INTEGER
313-
*> The length of the array RWORK. LRWORK >= max(1,24*N).
314+
*> The length of the array RWORK.
315+
*> If N <= 1, LRWORK >= 1, else LRWORK >= 24*N.
314316
*>
315317
*> If LRWORK = -1, then a workspace query is assumed; the
316318
*> routine only calculates the optimal sizes of the WORK, RWORK
@@ -329,7 +331,8 @@
329331
*> \param[in] LIWORK
330332
*> \verbatim
331333
*> LIWORK is INTEGER
332-
*> The dimension of the array IWORK. LIWORK >= max(1,10*N).
334+
*> The dimension of the array IWORK.
335+
*> If N <= 1, LIWORK >= 1, else LIWORK >= 10*N.
333336
*>
334337
*> If LIWORK = -1, then a workspace query is assumed; the
335338
*> routine only calculates the optimal sizes of the WORK, RWORK
@@ -473,9 +476,16 @@ SUBROUTINE CHEEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU,
473476
IB = ILAENV2STAGE( 2, 'CHETRD_2STAGE', JOBZ, N, KD, -1, -1 )
474477
LHTRD = ILAENV2STAGE( 3, 'CHETRD_2STAGE', JOBZ, N, KD, IB, -1 )
475478
LWTRD = ILAENV2STAGE( 4, 'CHETRD_2STAGE', JOBZ, N, KD, IB, -1 )
476-
LWMIN = N + LHTRD + LWTRD
477-
LRWMIN = MAX( 1, 24*N )
478-
LIWMIN = MAX( 1, 10*N )
479+
*
480+
IF( N.LE.1 ) THEN
481+
LWMIN = 1
482+
LRWMIN = 1
483+
LIWMIN = 1
484+
ELSE
485+
LWMIN = N + LHTRD + LWTRD
486+
LRWMIN = 24*N
487+
LIWMIN = 10*N
488+
END IF
479489
*
480490
INFO = 0
481491
IF( .NOT.( LSAME( JOBZ, 'N' ) ) ) THEN
@@ -508,7 +518,7 @@ SUBROUTINE CHEEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU,
508518
*
509519
IF( INFO.EQ.0 ) THEN
510520
WORK( 1 ) = SROUNDUP_LWORK( LWMIN )
511-
RWORK( 1 ) = LRWMIN
521+
RWORK( 1 ) = SROUNDUP_LWORK( LRWMIN )
512522
IWORK( 1 ) = LIWMIN
513523
*
514524
IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
@@ -536,7 +546,7 @@ SUBROUTINE CHEEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU,
536546
END IF
537547
*
538548
IF( N.EQ.1 ) THEN
539-
WORK( 1 ) = 2
549+
WORK( 1 ) = 1
540550
IF( ALLEIG .OR. INDEIG ) THEN
541551
M = 1
542552
W( 1 ) = REAL( A( 1, 1 ) )
@@ -767,7 +777,7 @@ SUBROUTINE CHEEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU,
767777
* Set WORK(1) to optimal workspace size.
768778
*
769779
WORK( 1 ) = SROUNDUP_LWORK( LWMIN )
770-
RWORK( 1 ) = LRWMIN
780+
RWORK( 1 ) = SROUNDUP_LWORK( LRWMIN )
771781
IWORK( 1 ) = LIWMIN
772782
*
773783
RETURN

SRC/dsyevr.f

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,8 @@
271271
*> \param[in] LWORK
272272
*> \verbatim
273273
*> LWORK is INTEGER
274-
*> The dimension of the array WORK. LWORK >= max(1,26*N).
274+
*> The dimension of the array WORK.
275+
*> If N <= 1, LWORK >= 1, else LWORK >= 26*N.
275276
*> For optimal efficiency, LWORK >= (NB+6)*N,
276277
*> where NB is the max of the blocksize for DSYTRD and DORMTR
277278
*> returned by ILAENV.
@@ -285,13 +286,14 @@
285286
*> \param[out] IWORK
286287
*> \verbatim
287288
*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))
288-
*> On exit, if INFO = 0, IWORK(1) returns the optimal LWORK.
289+
*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
289290
*> \endverbatim
290291
*>
291292
*> \param[in] LIWORK
292293
*> \verbatim
293294
*> LIWORK is INTEGER
294-
*> The dimension of the array IWORK. LIWORK >= max(1,10*N).
295+
*> The dimension of the array IWORK.
296+
*> If N <= 1, LIWORK >= 1, else LIWORK >= 10*N.
295297
*>
296298
*> If LIWORK = -1, then a workspace query is assumed; the
297299
*> routine only calculates the optimal size of the IWORK array,
@@ -390,8 +392,13 @@ SUBROUTINE DSYEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
390392
*
391393
LQUERY = ( ( LWORK.EQ.-1 ) .OR. ( LIWORK.EQ.-1 ) )
392394
*
393-
LWMIN = MAX( 1, 26*N )
394-
LIWMIN = MAX( 1, 10*N )
395+
IF( N.LE.1 ) THEN
396+
LWMIN = 1
397+
LIWMIN = 1
398+
ELSE
399+
LWMIN = 26*N
400+
LIWMIN = 10*N
401+
END IF
395402
*
396403
INFO = 0
397404
IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
@@ -450,7 +457,7 @@ SUBROUTINE DSYEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
450457
END IF
451458
*
452459
IF( N.EQ.1 ) THEN
453-
WORK( 1 ) = 7
460+
WORK( 1 ) = 1
454461
IF( ALLEIG .OR. INDEIG ) THEN
455462
M = 1
456463
W( 1 ) = A( 1, 1 )

SRC/dsyevr_2stage.f

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ SUBROUTINE DSYEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU,
492492
* NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )
493493
* NB = MAX( NB, ILAENV( 1, 'DORMTR', UPLO, N, -1, -1, -1 ) )
494494
* LWKOPT = MAX( ( NB+1 )*N, LWMIN )
495-
WORK( 1 ) = LWMIN
495+
WORK( 1 ) = LWMIN
496496
IWORK( 1 ) = LIWMIN
497497
END IF
498498
*
@@ -735,7 +735,7 @@ SUBROUTINE DSYEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU,
735735
*
736736
* Set WORK(1) to optimal workspace size.
737737
*
738-
WORK( 1 ) = LWMIN
738+
WORK( 1 ) = LWMIN
739739
IWORK( 1 ) = LIWMIN
740740
*
741741
RETURN

SRC/ssyevr.f

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,8 @@
271271
*> \param[in] LWORK
272272
*> \verbatim
273273
*> LWORK is INTEGER
274-
*> The dimension of the array WORK. LWORK >= max(1,26*N).
274+
*> The dimension of the array WORK.
275+
*> If N <= 1, LWORK >= 1, else LWORK >= 26*N.
275276
*> For optimal efficiency, LWORK >= (NB+6)*N,
276277
*> where NB is the max of the blocksize for SSYTRD and SORMTR
277278
*> returned by ILAENV.
@@ -292,7 +293,8 @@
292293
*> \param[in] LIWORK
293294
*> \verbatim
294295
*> LIWORK is INTEGER
295-
*> The dimension of the array IWORK. LIWORK >= max(1,10*N).
296+
*> The dimension of the array IWORK.
297+
*> If N <= 1, LIWORK >= 1, else LIWORK >= 10*N.
296298
*>
297299
*> If LIWORK = -1, then a workspace query is assumed; the
298300
*> routine only calculates the optimal sizes of the WORK and
@@ -392,8 +394,13 @@ SUBROUTINE SSYEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
392394
*
393395
LQUERY = ( ( LWORK.EQ.-1 ) .OR. ( LIWORK.EQ.-1 ) )
394396
*
395-
LWMIN = MAX( 1, 26*N )
396-
LIWMIN = MAX( 1, 10*N )
397+
IF( N.LE.1 ) THEN
398+
LWMIN = 1
399+
LIWMIN = 1
400+
ELSE
401+
LWMIN = 26*N
402+
LIWMIN = 10*N
403+
END IF
397404
*
398405
INFO = 0
399406
IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN

SRC/ssyevr_2stage.f

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ SUBROUTINE SSYEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU,
493493
* NB = ILAENV( 1, 'SSYTRD', UPLO, N, -1, -1, -1 )
494494
* NB = MAX( NB, ILAENV( 1, 'SORMTR', UPLO, N, -1, -1, -1 ) )
495495
* LWKOPT = MAX( ( NB+1 )*N, LWMIN )
496-
WORK( 1 ) = SROUNDUP_LWORK( LWMIN )
496+
WORK( 1 ) = SROUNDUP_LWORK( LWMIN )
497497
IWORK( 1 ) = LIWMIN
498498
END IF
499499
*
@@ -741,7 +741,7 @@ SUBROUTINE SSYEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU,
741741
*
742742
* Set WORK(1) to optimal workspace size.
743743
*
744-
WORK( 1 ) = SROUNDUP_LWORK( LWMIN )
744+
WORK( 1 ) = SROUNDUP_LWORK( LWMIN )
745745
IWORK( 1 ) = LIWMIN
746746
*
747747
RETURN

SRC/zheevr.f

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@
272272
*> \param[in] LWORK
273273
*> \verbatim
274274
*> LWORK is INTEGER
275-
*> The length of the array WORK. LWORK >= max(1,2*N).
275+
*> The length of the array WORK.
276+
*> If N <= 1, LWORK >= 1, else LWORK >= 2*N.
276277
*> For optimal efficiency, LWORK >= (NB+1)*N,
277278
*> where NB is the max of the blocksize for ZHETRD and for
278279
*> ZUNMTR as returned by ILAENV.
@@ -294,7 +295,8 @@
294295
*> \param[in] LRWORK
295296
*> \verbatim
296297
*> LRWORK is INTEGER
297-
*> The length of the array RWORK. LRWORK >= max(1,24*N).
298+
*> The length of the array RWORK.
299+
*> If N <= 1, LRWORK >= 1, else LRWORK >= 24*N.
298300
*>
299301
*> If LRWORK = -1, then a workspace query is assumed; the
300302
*> routine only calculates the optimal sizes of the WORK, RWORK
@@ -313,7 +315,8 @@
313315
*> \param[in] LIWORK
314316
*> \verbatim
315317
*> LIWORK is INTEGER
316-
*> The dimension of the array IWORK. LIWORK >= max(1,10*N).
318+
*> The dimension of the array IWORK.
319+
*> If N <= 1, LIWORK >= 1, else LIWORK >= 10*N.
317320
*>
318321
*> If LIWORK = -1, then a workspace query is assumed; the
319322
*> routine only calculates the optimal sizes of the WORK, RWORK
@@ -417,9 +420,15 @@ SUBROUTINE ZHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
417420
LQUERY = ( ( LWORK.EQ.-1 ) .OR. ( LRWORK.EQ.-1 ) .OR.
418421
$ ( LIWORK.EQ.-1 ) )
419422
*
420-
LRWMIN = MAX( 1, 24*N )
421-
LIWMIN = MAX( 1, 10*N )
422-
LWMIN = MAX( 1, 2*N )
423+
IF( N.LE.1 ) THEN
424+
LWMIN = 1
425+
LRWMIN = 1
426+
LIWMIN = 1
427+
ELSE
428+
LWMIN = 2*N
429+
LRWMIN = 24*N
430+
LIWMIN = 10*N
431+
END IF
423432
*
424433
INFO = 0
425434
IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
@@ -454,7 +463,7 @@ SUBROUTINE ZHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
454463
NB = ILAENV( 1, 'ZHETRD', UPLO, N, -1, -1, -1 )
455464
NB = MAX( NB, ILAENV( 1, 'ZUNMTR', UPLO, N, -1, -1, -1 ) )
456465
LWKOPT = MAX( ( NB+1 )*N, LWMIN )
457-
WORK( 1 ) = LWKOPT
466+
WORK( 1 ) = LWKOPT
458467
RWORK( 1 ) = LRWMIN
459468
IWORK( 1 ) = LIWMIN
460469
*
@@ -483,7 +492,7 @@ SUBROUTINE ZHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
483492
END IF
484493
*
485494
IF( N.EQ.1 ) THEN
486-
WORK( 1 ) = 2
495+
WORK( 1 ) = 1
487496
IF( ALLEIG .OR. INDEIG ) THEN
488497
M = 1
489498
W( 1 ) = DBLE( A( 1, 1 ) )
@@ -710,7 +719,7 @@ SUBROUTINE ZHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
710719
*
711720
* Set WORK(1) to optimal workspace size.
712721
*
713-
WORK( 1 ) = LWKOPT
722+
WORK( 1 ) = LWKOPT
714723
RWORK( 1 ) = LRWMIN
715724
IWORK( 1 ) = LIWMIN
716725
*

0 commit comments

Comments
 (0)