@@ -23,13 +23,17 @@ module test_linalg_eigenvalues
2323 #:for rk,rt,ri in REAL_KINDS_TYPES
2424 #:if rk!="xdp"
2525 tests = [tests,new_unittest("test_eig_real_${ri}$",test_eig_real_${ri}$), &
26+ new_unittest("test_eigvals_identity_${ri}$",test_eigvals_identity_${ri}$), &
27+ new_unittest("test_eigvals_diagonal_B_${ri}$",test_eigvals_diagonal_B_${ri}$), &
28+ new_unittest("test_eigvals_nondiagonal_B_${ri}$",test_eigvals_nondiagonal_B_${ri}$), &
2629 new_unittest("test_eigh_real_${ri}$",test_eigh_real_${ri}$)]
2730 #:endif
2831 #: endfor
2932
3033 #:for ck,ct,ci in CMPLX_KINDS_TYPES
3134 #:if ck!="xdp"
32- tests = [tests,new_unittest("test_eig_complex_${ci}$",test_eig_complex_${ci}$)]
35+ tests = [tests,new_unittest("test_eig_complex_${ci}$",test_eig_complex_${ci}$), &
36+ new_unittest("test_eig_generalized_complex_${ci}$",test_eigvals_generalized_complex_${ci}$)]
3337 #:endif
3438 #: endfor
3539
@@ -131,6 +135,110 @@ module test_linalg_eigenvalues
131135
132136 end subroutine test_eigh_real_${ri}$
133137
138+ !> Test generalized eigenvalue problem with B = identity
139+ subroutine test_eigvals_identity_${ri}$(error)
140+ type(error_type), allocatable, intent(out) :: error
141+
142+ !> Reference solution
143+ real(${rk}$), parameter :: zero = 0.0_${rk}$
144+ real(${rk}$), parameter :: tol = sqrt(epsilon(zero))
145+
146+ !> Local variables
147+ type(linalg_state_type) :: state
148+ ${rt}$ :: A(3, 3), B(3, 3)
149+ complex(${rk}$) :: lambda(3)
150+
151+ !> Matrix A
152+ A = reshape([3, 0, 0, &
153+ 0, 5, 0, &
154+ 0, 0, 7], [3, 3])
155+
156+ !> Identity matrix B
157+ B = reshape([1, 0, 0, &
158+ 0, 1, 0, &
159+ 0, 0, 1], [3, 3])
160+
161+ !> Generalized problem
162+ lambda = eigvals(A, B, err=state)
163+
164+ call check(error, state%ok(), state%print())
165+ if (allocated(error)) return
166+
167+ call check(error, all(abs(real(lambda,${rk}$) - [3, 5, 7]) <= tol), &
168+ 'expected results for B=identity')
169+ if (allocated(error)) return
170+ end subroutine test_eigvals_identity_${ri}$
171+
172+ !> Test generalized eigenvalue problem with B = diagonal
173+ subroutine test_eigvals_diagonal_B_${ri}$(error)
174+ type(error_type), allocatable, intent(out) :: error
175+
176+ !> Reference solution
177+ real(${rk}$), parameter :: zero = 0.0_${rk}$
178+ real(${rk}$), parameter :: tol = sqrt(epsilon(zero))
179+
180+ !> Local variables
181+ type(linalg_state_type) :: state
182+ ${rt}$ :: A(3, 3), B(3, 3)
183+ complex(${rk}$) :: lambda(3)
184+
185+ !> Matrix A
186+ A = reshape([3, 0, 0, &
187+ 0, 5, 0, &
188+ 0, 0, 7], [3, 3])
189+
190+ !> Diagonal matrix B
191+ B = reshape([2, 0, 0, &
192+ 0, 4, 0, &
193+ 0, 0, 8], [3, 3])
194+
195+ lambda = eigvals(A, B, err=state)
196+
197+ call check(error, state%ok(), state%print())
198+ if (allocated(error)) return
199+
200+ call check(error, all(abs(real(lambda,${rk}$) - [1.5_${rk}$, 1.25_${rk}$, 0.875_${rk}$]) <= tol),&
201+ 'expected results for B=diagonal')
202+ if (allocated(error)) return
203+
204+ end subroutine test_eigvals_diagonal_B_${ri}$
205+
206+ !> Test generalized eigenvalue problem with B = non-diagonal
207+ subroutine test_eigvals_nondiagonal_B_${ri}$(error)
208+ type(error_type), allocatable, intent(out) :: error
209+
210+ !> Reference solution
211+ real(${rk}$), parameter :: zero = 0.0_${rk}$
212+ real(${rk}$), parameter :: tol = 1.0e-3_${rk}$
213+
214+ !> Local variables
215+ type(linalg_state_type) :: state
216+ ${rt}$ :: A(3, 3), B(3, 3)
217+ complex(${rk}$) :: lambda(3)
218+
219+ !> Matrix A
220+ A = reshape([3, 2, 0, &
221+ 2, 5, 1, &
222+ 0, 1, 7], [3, 3])
223+
224+ !> Non-diagonal matrix B
225+ B = reshape([2, 1, 0, &
226+ 1, 3, 0, &
227+ 0, 0, 4], [3, 3])
228+
229+ lambda = eigvals(A, B, err=state)
230+
231+ call check(error, state%ok(), state%print())
232+ if (allocated(error)) return
233+
234+ call check(error, all(abs(lambda - [1.1734_${rk}$, 1.5766_${rk}$, 2.0000_${rk}$]) <= tol), 'expected results for B=nondiagonal')
235+
236+ print *, 'lambda ',lambda
237+ print *, 'expected ',[1.0,2.5,3.75]
238+
239+ if (allocated(error)) return
240+ end subroutine test_eigvals_nondiagonal_B_${ri}$
241+
134242 #:endif
135243 #:endfor
136244
@@ -177,6 +285,45 @@ module test_linalg_eigenvalues
177285
178286 end subroutine test_eig_complex_${ci}$
179287
288+ !> Complex generalized eigenvalue problem with eigvals
289+ subroutine test_eigvals_generalized_complex_${ci}$(error)
290+ type(error_type), allocatable, intent(out) :: error
291+
292+ !> Reference solution
293+ real(${ck}$), parameter :: zero = 0.0_${ck}$
294+ real(${ck}$), parameter :: one = 1.0_${ck}$
295+ real(${ck}$), parameter :: tol = sqrt(epsilon(zero))
296+ ${ct}$, parameter :: cone = (one, zero)
297+ ${ct}$, parameter :: cimg = (zero, one)
298+ ${ct}$, parameter :: czero = (zero, zero)
299+
300+ !> Local variables
301+ type(linalg_state_type) :: state
302+ ${ct}$ :: A(2,2), B(2,2), lambda(2), lres(2)
303+
304+ !> Matrices A and B for the generalized problem A * x = lambda * B * x
305+ A = transpose(reshape([ cone, cimg, &
306+ -cimg, cone], [2,2]))
307+ B = transpose(reshape([ cone, czero, &
308+ czero, cone], [2,2]))
309+
310+ lambda = eigvals(A, B, err=state)
311+
312+ print *, 'lambda = ',lambda
313+
314+ !> Expected eigenvalues
315+ lres(1) = czero
316+ lres(2) = 2*cone
317+
318+ call check(error, state%ok(), state%print())
319+ if (allocated(error)) return
320+
321+ call check(error, all(abs(lambda - lres) <= tol) .or. &
322+ all(abs(lambda - lres([2,1])) <= tol), 'results match expected')
323+ if (allocated(error)) return
324+
325+ end subroutine test_eigvals_generalized_complex_${ci}$
326+
180327 #:endif
181328 #:endfor
182329
0 commit comments