@@ -20,10 +20,18 @@ contains
2020
2121 testsuite = [ &
2222 new_unittest('tridiagonal', test_tridiagonal), &
23- new_unittest('tridiagonal error handling', test_tridiagonal_error_handling) &
23+ new_unittest('tridiagonal error handling', test_tridiagonal_error_handling), &
24+ new_unittest('symtridiagonal', test_symtridiagonal), &
25+ new_unittest('symtridiagonal error handling', test_symtridiagonal_error_handling) &
2426 ]
2527 end subroutine
2628
29+ !----------------------------------------
30+ !----- -----
31+ !----- TRIDIAGONAL MATRICES -----
32+ !----- -----
33+ !----------------------------------------
34+
2735 subroutine test_tridiagonal(error)
2836 !> Error handling
2937 type(error_type), allocatable, intent(out) :: error
@@ -94,6 +102,82 @@ contains
94102 #:endfor
95103 end subroutine
96104
105+ !--------------------------------------------------
106+ !----- -----
107+ !----- SYMMETRIC TRIDIAGONAL MATRICES -----
108+ !----- -----
109+ !--------------------------------------------------
110+
111+ subroutine test_symtridiagonal(error)
112+ !> Error handling
113+ type(error_type), allocatable, intent(out) :: error
114+ #:for k1, t1, s1 in (KINDS_TYPES)
115+ block
116+ integer, parameter :: wp = ${k1}$
117+ integer, parameter :: n = 5
118+ type(symtridiagonal_${s1}$_type) :: A
119+ ${t1}$, allocatable :: Amat(:,:), dv(:), ev(:)
120+ ${t1}$, allocatable :: x(:)
121+ ${t1}$, allocatable :: y1(:), y2(:)
122+
123+ ! Initialize matrix.
124+ allocate(ev(n-1), dv(n))
125+ call random_number(dv) ; call random_number(ev)
126+ A = symtridiagonal(dv, ev) ; Amat = dense(A)
127+
128+ ! Random vectors.
129+ allocate(x(n), source = 0.0_wp) ; call random_number(x)
130+ allocate(y1(n), source = 0.0_wp) ; allocate(y2(n), source=0.0_wp)
131+
132+ ! Test y = A @ x
133+ y1 = matmul(Amat, x) ; call spmv(A, x, y2)
134+ call check(error, all_close(y1, y2), .true.)
135+ if (allocated(error)) return
136+
137+ ! Test y = A.T @ x
138+ y1 = 0.0_wp ; y2 = 0.0_wp
139+ y1 = matmul(transpose(Amat), x) ; call spmv(A, x, y2, op="T")
140+ call check(error, all_close(y1, y2), .true.)
141+ if (allocated(error)) return
142+
143+ #:if t1.startswith('complex')
144+ ! Test y = A.H @ x
145+ y1 = 0.0_wp ; y2 = 0.0_wp
146+ y1 = matmul(hermitian(Amat), x) ; call spmv(A, x, y2, op="H")
147+ call check(error, all_close(y1, y2), .true.)
148+ if (allocated(error)) return
149+ #:endif
150+ end block
151+ #:endfor
152+ end subroutine
153+
154+ subroutine test_symtridiagonal_error_handling(error)
155+ !> Error handling
156+ type(error_type), allocatable, intent(out) :: error
157+ #:for k1, t1, s1 in (KINDS_TYPES)
158+ block
159+ integer, parameter :: wp = ${k1}$
160+ integer, parameter :: n = 5
161+ type(symtridiagonal_${s1}$_type) :: A
162+ ${t1}$, allocatable :: dv(:), ev(:)
163+ type(linalg_state_type) :: state
164+ integer :: i
165+
166+ !> Test constructor from arrays.
167+ ev = [(1.0_wp, i = 1, n-2)]
168+ dv = [(2.0_wp, i = 1, n)]
169+ A = symtridiagonal(dv, ev, state)
170+ call check(error, state%ok(), .false.)
171+ if (allocated(error)) return
172+
173+ !> Test contructor from constants.
174+ A = symtridiagonal(dv(1), ev(1), -n, state)
175+ call check(error, state%ok(), .false.)
176+ if (allocated(error)) return
177+ end block
178+ #:endfor
179+ end subroutine
180+
97181end module
98182
99183
0 commit comments