@@ -5170,9 +5170,9 @@ solution `X`.
5170
5170
hetrs! (uplo:: AbstractChar , A:: AbstractMatrix , ipiv:: AbstractVector{BlasInt} , B:: AbstractVecOrMat )
5171
5171
5172
5172
# Symmetric (real) eigensolvers
5173
- for (syev, syevr, sygvd, elty) in
5174
- ((:dsyev_ ,:dsyevr_ ,:dsygvd_ ,:Float64 ),
5175
- (:ssyev_ ,:ssyevr_ ,:ssygvd_ ,:Float32 ))
5173
+ for (syev, syevr, syevd, sygvd, elty) in
5174
+ ((:dsyev_ ,:dsyevr_ ,:dsyevd_ , : dsygvd_ ,:Float64 ),
5175
+ (:ssyev_ ,:ssyevr_ ,:ssyevd_ , : ssygvd_ ,:Float32 ))
5176
5176
@eval begin
5177
5177
# SUBROUTINE DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )
5178
5178
# * .. Scalar Arguments ..
@@ -5225,7 +5225,7 @@ for (syev, syevr, sygvd, elty) in
5225
5225
end
5226
5226
lda = stride (A,2 )
5227
5227
m = Ref {BlasInt} ()
5228
- w = similar (A, $ elty, n)
5228
+ W = similar (A, $ elty, n)
5229
5229
ldz = n
5230
5230
if jobz == ' N'
5231
5231
Z = similar (A, $ elty, ldz, 0 )
@@ -5249,7 +5249,7 @@ for (syev, syevr, sygvd, elty) in
5249
5249
jobz, range, uplo, n,
5250
5250
A, max (1 ,lda), vl, vu,
5251
5251
il, iu, abstol, m,
5252
- w , Z, max (1 ,ldz), isuppz,
5252
+ W , Z, max (1 ,ldz), isuppz,
5253
5253
work, lwork, iwork, liwork,
5254
5254
info, 1 , 1 , 1 )
5255
5255
chklapackerror (info[])
@@ -5260,11 +5260,51 @@ for (syev, syevr, sygvd, elty) in
5260
5260
resize! (iwork, liwork)
5261
5261
end
5262
5262
end
5263
- w [1 : m[]], Z[:,1 : (jobz == ' V' ? m[] : 0 )]
5263
+ W [1 : m[]], Z[:,1 : (jobz == ' V' ? m[] : 0 )]
5264
5264
end
5265
5265
syevr! (jobz:: AbstractChar , A:: AbstractMatrix{$elty} ) =
5266
5266
syevr! (jobz, ' A' , ' U' , A, 0.0 , 0.0 , 0 , 0 , - 1.0 )
5267
5267
5268
+ # SUBROUTINE DSYEVD( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK,
5269
+ # $ IWORK, LIWORK, INFO )
5270
+ # * .. Scalar Arguments ..
5271
+ # CHARACTER JOBZ, UPLO
5272
+ # INTEGER INFO, LDA, LIWORK, LWORK, N
5273
+ # * ..
5274
+ # * .. Array Arguments ..
5275
+ # INTEGER IWORK( * )
5276
+ # DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * )
5277
+ function syevd! (jobz:: AbstractChar , uplo:: AbstractChar , A:: AbstractMatrix{$elty} )
5278
+ chkstride1 (A)
5279
+ n = checksquare (A)
5280
+ chkuplofinite (A, uplo)
5281
+ lda = stride (A,2 )
5282
+ m = Ref {BlasInt} ()
5283
+ W = similar (A, $ elty, n)
5284
+ work = Vector {$elty} (undef, 1 )
5285
+ lwork = BlasInt (- 1 )
5286
+ iwork = Vector {BlasInt} (undef, 1 )
5287
+ liwork = BlasInt (- 1 )
5288
+ info = Ref {BlasInt} ()
5289
+ for i = 1 : 2 # first call returns lwork as work[1] and liwork as iwork[1]
5290
+ ccall ((@blasfunc ($ syevd), libblastrampoline), Cvoid,
5291
+ (Ref{UInt8}, Ref{UInt8}, Ref{BlasInt}, Ptr{$ elty}, Ref{BlasInt},
5292
+ Ptr{$ elty}, Ptr{$ elty}, Ref{BlasInt}, Ptr{BlasInt}, Ref{BlasInt},
5293
+ Ptr{BlasInt}, Clong, Clong),
5294
+ jobz, uplo, n, A, max (1 ,lda),
5295
+ W, work, lwork, iwork, liwork,
5296
+ info, 1 , 1 )
5297
+ chklapackerror (info[])
5298
+ if i == 1
5299
+ lwork = BlasInt (real (work[1 ]))
5300
+ resize! (work, lwork)
5301
+ liwork = iwork[1 ]
5302
+ resize! (iwork, liwork)
5303
+ end
5304
+ end
5305
+ jobz == ' V' ? (W, A) : W
5306
+ end
5307
+
5268
5308
# Generalized eigenproblem
5269
5309
# SUBROUTINE DSYGVD( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,
5270
5310
# $ LWORK, IWORK, LIWORK, INFO )
@@ -5313,9 +5353,9 @@ for (syev, syevr, sygvd, elty) in
5313
5353
end
5314
5354
end
5315
5355
# Hermitian eigensolvers
5316
- for (syev, syevr, sygvd, elty, relty) in
5317
- ((:zheev_ ,:zheevr_ ,:zhegvd_ ,:ComplexF64 ,:Float64 ),
5318
- (:cheev_ ,:cheevr_ ,:chegvd_ ,:ComplexF32 ,:Float32 ))
5356
+ for (syev, syevr, syevd, sygvd, elty, relty) in
5357
+ ((:zheev_ ,:zheevr_ ,:zheevd_ , : zhegvd_ ,:ComplexF64 ,:Float64 ),
5358
+ (:cheev_ ,:cheevr_ ,:cheevd_ , : chegvd_ ,:ComplexF32 ,:Float32 ))
5319
5359
@eval begin
5320
5360
# SUBROUTINE ZHEEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, RWORK, INFO )
5321
5361
# * .. Scalar Arguments ..
@@ -5376,7 +5416,7 @@ for (syev, syevr, sygvd, elty, relty) in
5376
5416
end
5377
5417
lda = max (1 ,stride (A,2 ))
5378
5418
m = Ref {BlasInt} ()
5379
- w = similar (A, $ relty, n)
5419
+ W = similar (A, $ relty, n)
5380
5420
if jobz == ' N'
5381
5421
ldz = 1
5382
5422
Z = similar (A, $ elty, ldz, 0 )
@@ -5404,7 +5444,7 @@ for (syev, syevr, sygvd, elty, relty) in
5404
5444
jobz, range, uplo, n,
5405
5445
A, lda, vl, vu,
5406
5446
il, iu, abstol, m,
5407
- w , Z, ldz, isuppz,
5447
+ W , Z, ldz, isuppz,
5408
5448
work, lwork, rwork, lrwork,
5409
5449
iwork, liwork, info,
5410
5450
1 , 1 , 1 )
@@ -5418,11 +5458,56 @@ for (syev, syevr, sygvd, elty, relty) in
5418
5458
resize! (iwork, liwork)
5419
5459
end
5420
5460
end
5421
- w [1 : m[]], Z[:,1 : (jobz == ' V' ? m[] : 0 )]
5461
+ W [1 : m[]], Z[:,1 : (jobz == ' V' ? m[] : 0 )]
5422
5462
end
5423
5463
syevr! (jobz:: AbstractChar , A:: AbstractMatrix{$elty} ) =
5424
5464
syevr! (jobz, ' A' , ' U' , A, 0.0 , 0.0 , 0 , 0 , - 1.0 )
5425
5465
5466
+ # SUBROUTINE ZHEEVD( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, RWORK,
5467
+ # $ LRWORK, IWORK, LIWORK, INFO )
5468
+ # * .. Scalar Arguments ..
5469
+ # CHARACTER JOBZ, UPLO
5470
+ # INTEGER INFO, LDA, LIWORK, LRWORK, LWORK, N
5471
+ # * ..
5472
+ # * .. Array Arguments ..
5473
+ # INTEGER IWORK( * )
5474
+ # DOUBLE PRECISION RWORK( * )
5475
+ # COMPLEX*16 A( LDA, * ), WORK( * )
5476
+ function syevd! (jobz:: AbstractChar , uplo:: AbstractChar , A:: AbstractMatrix{$elty} )
5477
+ chkstride1 (A)
5478
+ chkuplofinite (A, uplo)
5479
+ n = checksquare (A)
5480
+ lda = max (1 , stride (A,2 ))
5481
+ m = Ref {BlasInt} ()
5482
+ W = similar (A, $ relty, n)
5483
+ work = Vector {$elty} (undef, 1 )
5484
+ lwork = BlasInt (- 1 )
5485
+ rwork = Vector {$relty} (undef, 1 )
5486
+ lrwork = BlasInt (- 1 )
5487
+ iwork = Vector {BlasInt} (undef, 1 )
5488
+ liwork = BlasInt (- 1 )
5489
+ info = Ref {BlasInt} ()
5490
+ for i = 1 : 2 # first call returns lwork as work[1], lrwork as rwork[1] and liwork as iwork[1]
5491
+ ccall ((@blasfunc ($ syevd), liblapack), Cvoid,
5492
+ (Ref{UInt8}, Ref{UInt8}, Ref{BlasInt}, Ptr{$ elty}, Ref{BlasInt},
5493
+ Ptr{$ relty}, Ptr{$ elty}, Ref{BlasInt}, Ptr{$ relty}, Ref{BlasInt},
5494
+ Ptr{BlasInt}, Ref{BlasInt}, Ptr{BlasInt}, Clong, Clong),
5495
+ jobz, uplo, n, A, stride (A,2 ),
5496
+ W, work, lwork, rwork, lrwork,
5497
+ iwork, liwork, info, 1 , 1 )
5498
+ chklapackerror (info[])
5499
+ if i == 1
5500
+ lwork = BlasInt (real (work[1 ]))
5501
+ resize! (work, lwork)
5502
+ lrwork = BlasInt (rwork[1 ])
5503
+ resize! (rwork, lrwork)
5504
+ liwork = iwork[1 ]
5505
+ resize! (iwork, liwork)
5506
+ end
5507
+ end
5508
+ jobz == ' V' ? (W, A) : W
5509
+ end
5510
+
5426
5511
# SUBROUTINE ZHEGVD( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,
5427
5512
# $ LWORK, RWORK, LRWORK, IWORK, LIWORK, INFO )
5428
5513
# * .. Scalar Arguments ..
@@ -5504,6 +5589,20 @@ The eigenvalues are returned in `W` and the eigenvectors in `Z`.
5504
5589
syevr! (jobz:: AbstractChar , range:: AbstractChar , uplo:: AbstractChar , A:: AbstractMatrix ,
5505
5590
vl:: AbstractFloat , vu:: AbstractFloat , il:: Integer , iu:: Integer , abstol:: AbstractFloat )
5506
5591
5592
+ """
5593
+ syevd!(jobz, uplo, A)
5594
+
5595
+ Finds the eigenvalues (`jobz = N`) or eigenvalues and eigenvectors
5596
+ (`jobz = V`) of a symmetric matrix `A`. If `uplo = U`, the upper triangle
5597
+ of `A` is used. If `uplo = L`, the lower triangle of `A` is used.
5598
+
5599
+ Use the divide-and-conquer method, instead of the QR iteration used by
5600
+ `syev!` or multiple relatively robust representations used by `syevr!`.
5601
+ See James W. Demmel et al, SIAM J. Sci. Comput. 30, 3, 1508 (2008) for
5602
+ a comparison of the accuracy and performatce of different methods.
5603
+ """
5604
+ syevd! (jobz:: AbstractChar , uplo:: AbstractChar , A:: AbstractMatrix )
5605
+
5507
5606
"""
5508
5607
sygvd!(itype, jobz, uplo, A, B) -> (w, A, B)
5509
5608
0 commit comments