@@ -20,10 +20,18 @@ contains
20
20
21
21
testsuite = [ &
22
22
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) &
24
26
]
25
27
end subroutine
26
28
29
+ !----------------------------------------
30
+ !----- -----
31
+ !----- TRIDIAGONAL MATRICES -----
32
+ !----- -----
33
+ !----------------------------------------
34
+
27
35
subroutine test_tridiagonal(error)
28
36
!> Error handling
29
37
type(error_type), allocatable, intent(out) :: error
@@ -94,6 +102,82 @@ contains
94
102
#:endfor
95
103
end subroutine
96
104
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
+
97
181
end module
98
182
99
183
0 commit comments