@@ -15,6 +15,8 @@ submodule (stdlib_specialmatrices) tridiagonal_matrices
1515 !----- -----
1616 !--------------------------------
1717
18+ ! ----- Tridiagonal matrices -----
19+
1820 #:for k1, t1, s1 in (KINDS_TYPES)
1921 pure module function initialize_tridiagonal_pure_${s1}$(dl, dv, du) result(A)
2022 !! Construct a `tridiagonal` matrix from the rank-1 arrays
@@ -137,6 +139,123 @@ submodule (stdlib_specialmatrices) tridiagonal_matrices
137139 end function
138140 #:endfor
139141
142+ !----- Symmetric Tridiagonal matrices -----
143+
144+ #:for k1, t1, s1 in (KINDS_TYPES)
145+ pure module function initialize_symtridiagonal_pure_${s1}$(dv, ev) result(A)
146+ !! Construct a `symtridiagonal` matrix from the rank-1 arrays
147+ !! `dl`, `dv` and `du`.
148+ ${t1}$, intent(in) :: dv(:), ev(:)
149+ !! symtridiagonal matrix elements.
150+ type(symtridiagonal_${s1}$_type) :: A
151+ !! Corresponding symtridiagonal matrix.
152+
153+ ! Internal variables.
154+ integer(ilp) :: n
155+ type(linalg_state_type) :: err0
156+
157+ ! Sanity check.
158+ n = size(dv, kind=ilp)
159+ if (n <= 0) then
160+ err0 = linalg_state_type(this, LINALG_VALUE_ERROR, "Matrix size needs to be positive, n = ", n, ".")
161+ call linalg_error_handling(err0)
162+ endif
163+ if (size(ev, kind=ilp) /= n-1) then
164+ err0 = linalg_state_type(this, LINALG_VALUE_ERROR, "Vector ev does not have the correct length.")
165+ call linalg_error_handling(err0)
166+ endif
167+
168+ ! Description of the matrix.
169+ A%n = n
170+ ! Matrix elements.
171+ A%dl = ev ; A%dv = dv ; A%du = ev
172+ end function
173+
174+ pure module function initialize_constant_symtridiagonal_pure_${s1}$(dv, ev, n) result(A)
175+ !! Construct a `symtridiagonal` matrix with constant elements.
176+ ${t1}$, intent(in) :: dv, ev
177+ !! symtridiagonal matrix elements.
178+ integer(ilp), intent(in) :: n
179+ !! Matrix dimension.
180+ type(symtridiagonal_${s1}$_type) :: A
181+ !! Corresponding symtridiagonal matrix.
182+
183+ ! Internal variables.
184+ integer(ilp) :: i
185+ type(linalg_state_type) :: err0
186+
187+ ! Description of the matrix.
188+ A%n = n
189+ if (n <= 0) then
190+ err0 = linalg_state_type(this, LINALG_VALUE_ERROR, "Matrix size needs to be positive, n = ", n, ".")
191+ call linalg_error_handling(err0)
192+ endif
193+ ! Matrix elements.
194+ A%dl = [(ev, i = 1, n-1)]
195+ A%dv = [(dv, i = 1, n-1)]
196+ A%du = [(ev, i = 1, n-1)]
197+ end function
198+
199+ module function initialize_symtridiagonal_impure_${s1}$(dv, ev, err) result(A)
200+ !! Construct a `symtridiagonal` matrix from the rank-1 arrays
201+ !! `dl`, `dv` and `du`.
202+ ${t1}$, intent(in) :: dv(:), ev(:)
203+ !! symtridiagonal matrix elements.
204+ type(linalg_state_type), intent(out) :: err
205+ !! Error handling.
206+ type(symtridiagonal_${s1}$_type) :: A
207+ !! Corresponding symtridiagonal matrix.
208+
209+ ! Internal variables.
210+ integer(ilp) :: n
211+ type(linalg_state_type) :: err0
212+
213+ ! Sanity check.
214+ n = size(dv, kind=ilp)
215+ if (n <= 0) then
216+ err0 = linalg_state_type(this, LINALG_VALUE_ERROR, "Matrix size needs to be positive, n = ", n, ".")
217+ call linalg_error_handling(err0, err)
218+ endif
219+ if (size(ev, kind=ilp) /= n-1) then
220+ err0 = linalg_state_type(this, LINALG_VALUE_ERROR, "Vector ev does not have the correct length.")
221+ call linalg_error_handling(err0, err)
222+ endif
223+
224+ ! Description of the matrix.
225+ A%n = n
226+ ! Matrix elements.
227+ A%dl = ev ; A%dv = dv ; A%du = ev
228+ end function
229+
230+ module function initialize_constant_symtridiagonal_impure_${s1}$(dv, ev, n, err) result(A)
231+ !! Construct a `symtridiagonal` matrix with constant elements.
232+ ${t1}$, intent(in) :: dv, ev
233+ !! symtridiagonal matrix elements.
234+ integer(ilp), intent(in) :: n
235+ !! Matrix dimension.
236+ type(linalg_state_type), intent(out) :: err
237+ !! Error handling
238+ type(symtridiagonal_${s1}$_type) :: A
239+ !! Corresponding symtridiagonal matrix.
240+
241+ ! Internal variables.
242+ integer(ilp) :: i
243+ type(linalg_state_type) :: err0
244+
245+ ! Description of the matrix.
246+ A%n = n
247+ if (n <= 0) then
248+ err0 = linalg_state_type(this, LINALG_VALUE_ERROR, "Matrix size needs to be positive, n = ", n, ".")
249+ call linalg_error_handling(err0, err)
250+ endif
251+ ! Matrix elements.
252+ A%dl = [(ev, i = 1, n)]
253+ A%dv = [(dv, i = 1, n-1)]
254+ A%du = [(ev, i = 1, n)]
255+ end function
256+ #:endfor
257+
258+
140259 !-----------------------------------------
141260 !----- -----
142261 !----- MATRIX-VECTOR PRODUCT -----
@@ -294,7 +413,7 @@ submodule (stdlib_specialmatrices) tridiagonal_matrices
294413 C = tridiagonal(A%dl, A%dv, A%du)
295414 C%dl = C%dl + B%dl; C%dv = C%dv + B%dv; C%du = C%du + B%du
296415 type is(symtridiagonal_${s1}$_type)
297- ! SymTridiagonal + SymTridiagoanl = SymTridiagonal
416+ ! SymTridiagonal + SymTridiagonal = SymTridiagonal
298417 C = symtridiagonal(A%dv, A%du)
299418 C%dl = C%dl + B%dl; C%dv = C%dv + B%dv; C%du = C%dl
300419 end select
@@ -318,7 +437,7 @@ submodule (stdlib_specialmatrices) tridiagonal_matrices
318437 C = tridiagonal(A%dl, A%dv, A%du)
319438 C%dl = C%dl - B%dl; C%dv = C%dv - B%dv; C%du = C%du - B%du
320439 type is(symtridiagonal_${s1}$_type)
321- ! SymTridiagonal - SymTridiagoanl = SymTridiagonal
440+ ! SymTridiagonal - SymTridiagonal = SymTridiagonal
322441 C = symtridiagonal(A%dv, A%du)
323442 C%dl = C%dl - B%dl; C%dv = C%dv - B%dv; C%du = C%dl
324443 end select
0 commit comments