3submodule(
linalg) linalg_basic
11 module subroutine mtx_mult_mtx(transa, transb, alpha, a, b, beta, c, err)
13 logical,
intent(in) :: transa, transb
14 real(real64),
intent(in) :: alpha, beta
15 real(real64),
intent(in),
dimension(:,:) :: a, b
16 real(real64),
intent(inout),
dimension(:,:) :: c
17 class(errors),
intent(inout),
optional,
target :: err
20 real(real64),
parameter :: zero = 0.0d0
21 real(real64),
parameter :: one = 1.0d0
25 integer(int32) :: m, n, k, lda, ldb, flag
26 class(errors),
pointer :: errmgr
27 type(errors),
target :: deferr
28 character(len = :),
allocatable :: errmsg
49 if (
present(err))
then
58 if (
size(a, 2) /= m) flag = 4
60 if (
size(a, 1) /= m) flag = 4
63 if (
size(b, 2) /= k .or.
size(b, 1) /= n) flag = 5
65 if (
size(b, 1) /= k .or.
size(b, 2) /= n) flag = 5
69 allocate(
character(len = 256) :: errmsg)
71 "Matrix dimension mismatch. Input number ", flag, &
72 " was not sized correctly."
73 call errmgr%report_error(
"mtx_mult_mtx", errmsg, &
79 call dgemm(ta, tb, m, n, k, alpha, a, lda, b, ldb, beta, c, m)
86 module subroutine mtx_mult_vec(trans, alpha, a, b, beta, c, err)
88 logical,
intent(in) :: trans
89 real(real64),
intent(in) :: alpha, beta
90 real(real64),
intent(in),
dimension(:,:) :: a
91 real(real64),
intent(in),
dimension(:) :: b
92 real(real64),
intent(inout),
dimension(:) :: c
93 class(errors),
intent(inout),
optional,
target :: err
97 integer(int32) :: m, n, flag
98 class(errors),
pointer :: errmgr
99 type(errors),
target :: deferr
100 character(len = :),
allocatable :: errmsg
107 if (
present(err))
then
116 if (
size(b) /= m)
then
118 else if (
size(c) /= n)
then
122 if (
size(b) /= n)
then
124 else if (
size(c) /= m)
then
130 allocate(
character(len = 256) :: errmsg)
132 "Matrix dimension mismatch. Input number ", flag, &
133 " was not sized correctly."
134 call errmgr%report_error(
"mtx_mult_vec", errmsg, &
140 call dgemv(t, m, n, alpha, a, m, b, 1, beta, c, 1)
149 module subroutine cmtx_mult_mtx(opa, opb, alpha, a, b, beta, c, err)
151 integer(int32),
intent(in) :: opa, opb
152 complex(real64),
intent(in) :: alpha, beta
153 complex(real64),
intent(in),
dimension(:,:) :: a, b
154 complex(real64),
intent(inout),
dimension(:,:) :: c
155 class(errors),
intent(inout),
optional,
target :: err
158 real(real64),
parameter :: zero = 0.0d0
159 real(real64),
parameter :: one = 1.0d0
163 integer(int32) :: m, n, k, lda, ldb, flag
164 class(errors),
pointer :: errmgr
165 type(errors),
target :: deferr
166 character(len = :),
allocatable :: errmsg
171 if (opa == la_transpose)
then
175 else if (opa == la_hermitian_transpose)
then
184 if (opb == la_transpose)
then
187 else if (opb == la_hermitian_transpose)
then
194 if (
present(err))
then
202 if (opa == la_transpose .or. opa == la_hermitian_transpose)
then
203 if (
size(a, 2) /= m) flag = 4
205 if (
size(a, 1) /= m) flag = 4
207 if (opb == la_transpose .or. opb == la_hermitian_transpose)
then
208 if (
size(b, 2) /= k .or.
size(b, 1) /= n) flag = 5
210 if (
size(b, 1) /= k .or.
size(b, 2) /= n) flag = 5
214 allocate(
character(len = 256) :: errmsg)
216 "Matrix dimension mismatch. Input number ", flag, &
217 " was not sized correctly."
218 call errmgr%report_error(
"cmtx_mult_mtx", errmsg, &
224 call zgemm(ta, tb, m, n, k, alpha, a, lda, b, ldb, beta, c, m)
231 module subroutine cmtx_mult_vec(opa, alpha, a, b, beta, c, err)
233 integer(int32),
intent(in) :: opa
234 complex(real64),
intent(in) :: alpha, beta
235 complex(real64),
intent(in),
dimension(:,:) :: a
236 complex(real64),
intent(in),
dimension(:) :: b
237 complex(real64),
intent(inout),
dimension(:) :: c
238 class(errors),
intent(inout),
optional,
target :: err
242 integer(int32) :: m, n, flag
243 class(errors),
pointer :: errmgr
244 type(errors),
target :: deferr
245 character(len = :),
allocatable :: errmsg
250 if (opa == la_transpose)
then
252 else if (opa == la_hermitian_transpose)
then
257 if (
present(err))
then
265 if (opa == la_transpose .or. opa == la_hermitian_transpose)
then
266 if (
size(b) /= m)
then
268 else if (
size(c) /= n)
then
272 if (
size(b) /= n)
then
274 else if (
size(c) /= m)
then
280 allocate(
character(len = 256) :: errmsg)
282 "Matrix dimension mismatch. Input number ", flag, &
283 " was not sized correctly."
284 call errmgr%report_error(
"cmtx_mult_vec", errmsg, &
290 call zgemv(t, m, n, alpha, a, m, b, 1, beta, c, 1)
299 module subroutine rank1_update_dbl(alpha, x, y, a, err)
301 real(real64),
intent(in) :: alpha
302 real(real64),
intent(in),
dimension(:) :: x, y
303 real(real64),
intent(inout),
dimension(:,:) :: a
304 class(errors),
intent(inout),
optional,
target :: err
307 real(real64),
parameter :: zero = 0.0d0
310 integer(int32) :: j, m, n
312 class(errors),
pointer :: errmgr
313 type(errors),
target :: deferr
318 if (
present(err))
then
325 if (
size(a, 1) /= m .or.
size(a, 2) /= n)
then
327 call errmgr%report_error(
"rank1_update_dbl", &
328 "Matrix dimension mismatch.", la_array_size_error)
334 if (y(j) /= zero)
then
336 a(:,j) = a(:,j) + temp * x
344 module subroutine rank1_update_cmplx(alpha, x, y, a, err)
346 complex(real64),
intent(in) :: alpha
347 complex(real64),
intent(in),
dimension(:) :: x, y
348 complex(real64),
intent(inout),
dimension(:,:) :: a
349 class(errors),
intent(inout),
optional,
target :: err
352 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
355 integer(int32) :: j, m, n
356 complex(real64) :: temp
357 class(errors),
pointer :: errmgr
358 type(errors),
target :: deferr
363 if (
present(err))
then
370 if (
size(a, 1) /= m .or.
size(a, 2) /= n)
then
372 call errmgr%report_error(
"rank1_update_cmplx", &
373 "Matrix dimension mismatch.", la_array_size_error)
379 if (y(j) /= zero)
then
380 temp = alpha * conjg(y(j))
381 a(:,j) = a(:,j) + temp * x
389 module subroutine diag_mtx_mult_mtx(lside, trans, alpha, a, b, beta, c, err)
391 logical,
intent(in) :: lside, trans
392 real(real64) :: alpha, beta
393 real(real64),
intent(in),
dimension(:) :: a
394 real(real64),
intent(in),
dimension(:,:) :: b
395 real(real64),
intent(inout),
dimension(:,:) :: c
396 class(errors),
intent(inout),
optional,
target :: err
399 real(real64),
parameter :: zero = 0.0d0
400 real(real64),
parameter :: one = 1.0d0
403 integer(int32) :: i, m, n, k, nrowb, ncolb, flag
405 class(errors),
pointer :: errmgr
406 type(errors),
target :: deferr
407 character(len = :),
allocatable :: errmsg
415 if (
present(err))
then
429 if (nrowb /= n .or. ncolb < k) flag = 5
432 if (nrowb < k .or. ncolb /= n) flag = 5
441 if (ncolb /= m .or. nrowb < k) flag = 5
444 if (nrowb /= m .or. ncolb < k) flag = 5
450 allocate(
character(len = 256) :: errmsg)
451 write(errmsg, 100)
"Input number ", flag, &
452 " is not sized correctly."
453 call errmgr%report_error(
"diag_mtx_mult_mtx", trim(errmsg), &
460 if (beta == zero)
then
462 else if (beta /= one)
then
473 if (beta == zero)
then
475 else if (beta /= one)
then
476 c(i,:) = beta * c(i,:)
479 c(i,:) = c(i,:) + temp * b(:,i)
484 if (beta == zero)
then
486 else if (beta /= one)
then
487 c(i,:) = beta * c(i,:)
490 c(i,:) = c(i,:) + temp * b(i,:)
496 if (beta == zero)
then
499 c(k+1:m,:) = beta * c(k+1:m,:)
506 if (beta == zero)
then
508 else if (beta /= one)
then
509 c(:,i) = beta * c(:,i)
512 c(:,i) = c(:,i) + temp * b(i,:)
517 if (beta == zero)
then
519 else if (beta /= one)
then
520 c(:,i) = beta * c(:,i)
523 c(:,i) = c(:,i) + temp * b(:,i)
529 if (beta == zero)
then
531 else if (beta /= one)
then
532 c(:,k+1:m) = beta * c(:,k+1:m)
542 module subroutine diag_mtx_mult_mtx2(lside, alpha, a, b, err)
544 logical,
intent(in) :: lside
545 real(real64),
intent(in) :: alpha
546 real(real64),
intent(in),
dimension(:) :: a
547 real(real64),
intent(inout),
dimension(:,:) :: b
548 class(errors),
intent(inout),
optional,
target :: err
551 real(real64),
parameter :: zero = 0.0d0
552 real(real64),
parameter :: one = 1.0d0
555 integer(int32) :: i, m, n, k
557 class(errors),
pointer :: errmgr
558 type(errors),
target :: deferr
564 if (
present(err))
then
571 if ((lside .and. k > m) .or. (.not.lside .and. k > n))
then
573 call errmgr%report_error(
"diag_mtx_mult_mtx2", &
574 "Input number 3 is not sized correctly.", &
584 b(i,:) = temp * b(i,:)
586 if (m > k) b(k+1:m,:) = zero
591 b(:,i) = temp * b(:,i)
593 if (n > k) b(:,k+1:n) = zero
598 module subroutine diag_mtx_mult_mtx3(lside, trans, alpha, a, b, beta, c, err)
600 logical,
intent(in) :: lside, trans
601 real(real64) :: alpha, beta
602 complex(real64),
intent(in),
dimension(:) :: a
603 real(real64),
intent(in),
dimension(:,:) :: b
604 complex(real64),
intent(inout),
dimension(:,:) :: c
605 class(errors),
intent(inout),
optional,
target :: err
608 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
609 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
612 integer(int32) :: i, m, n, k, nrowb, ncolb, flag
613 complex(real64) :: temp
614 class(errors),
pointer :: errmgr
615 type(errors),
target :: deferr
616 character(len = :),
allocatable :: errmsg
624 if (
present(err))
then
638 if (nrowb /= n .or. ncolb < k) flag = 5
641 if (nrowb < k .or. ncolb /= n) flag = 5
650 if (ncolb /= m .or. nrowb < k) flag = 5
653 if (nrowb /= m .or. ncolb < k) flag = 5
659 allocate(
character(len = 256) :: errmsg)
660 write(errmsg, 100)
"Input number ", flag, &
661 " is not sized correctly."
662 call errmgr%report_error(
"diag_mtx_mult_mtx3", trim(errmsg), &
669 if (beta == zero)
then
671 else if (beta /= one)
then
682 if (beta == zero)
then
684 else if (beta /= one)
then
685 c(i,:) = beta * c(i,:)
688 c(i,:) = c(i,:) + temp * b(:,i)
693 if (beta == zero)
then
695 else if (beta /= one)
then
696 c(i,:) = beta * c(i,:)
699 c(i,:) = c(i,:) + temp * b(i,:)
705 if (beta == zero)
then
708 c(k+1:m,:) = beta * c(k+1:m,:)
715 if (beta == zero)
then
717 else if (beta /= one)
then
718 c(:,i) = beta * c(:,i)
721 c(:,i) = c(:,i) + temp * b(i,:)
726 if (beta == zero)
then
728 else if (beta /= one)
then
729 c(:,i) = beta * c(:,i)
732 c(:,i) = c(:,i) + temp * b(:,i)
738 if (beta == zero)
then
740 else if (beta /= one)
then
741 c(:,k+1:m) = beta * c(:,k+1:m)
751 module subroutine diag_mtx_mult_mtx4(lside, opb, alpha, a, b, beta, c, err)
753 logical,
intent(in) :: lside
754 integer(int32),
intent(in) :: opb
755 real(real64) :: alpha, beta
756 complex(real64),
intent(in),
dimension(:) :: a
757 complex(real64),
intent(in),
dimension(:,:) :: b
758 complex(real64),
intent(inout),
dimension(:,:) :: c
759 class(errors),
intent(inout),
optional,
target :: err
762 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
763 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
766 integer(int32) :: i, m, n, k, nrowb, ncolb, flag
767 complex(real64) :: temp
768 class(errors),
pointer :: errmgr
769 type(errors),
target :: deferr
770 character(len = :),
allocatable :: errmsg
778 if (
present(err))
then
790 if (opb == la_transpose .or. opb == la_hermitian_transpose)
then
792 if (nrowb /= n .or. ncolb < k) flag = 5
795 if (nrowb < k .or. ncolb /= n) flag = 5
802 if (opb == la_transpose .or. opb == la_hermitian_transpose)
then
804 if (ncolb /= m .or. nrowb < k) flag = 5
807 if (nrowb /= m .or. ncolb < k) flag = 5
813 allocate(
character(len = 256) :: errmsg)
814 write(errmsg, 100)
"Input number ", flag, &
815 " is not sized correctly."
816 call errmgr%report_error(
"diag_mtx_mult_mtx4", trim(errmsg), &
823 if (beta == zero)
then
825 else if (beta /= one)
then
833 if (opb == la_transpose)
then
836 if (beta == zero)
then
838 else if (beta /= one)
then
839 c(i,:) = beta * c(i,:)
842 c(i,:) = c(i,:) + temp * b(:,i)
844 else if (opb == la_hermitian_transpose)
then
847 if (beta == zero)
then
849 else if (beta /= one)
then
850 c(i,:) = beta * c(i,:)
853 c(i,:) = c(i,:) + temp * conjg(b(:,i))
858 if (beta == zero)
then
860 else if (beta /= one)
then
861 c(i,:) = beta * c(i,:)
864 c(i,:) = c(i,:) + temp * b(i,:)
870 if (beta == zero)
then
873 c(k+1:m,:) = beta * c(k+1:m,:)
877 if (opb == la_transpose)
then
880 if (beta == zero)
then
882 else if (beta /= one)
then
883 c(:,i) = beta * c(:,i)
886 c(:,i) = c(:,i) + temp * b(i,:)
888 else if (opb == la_hermitian_transpose)
then
891 if (beta == zero)
then
893 else if (beta /= one)
then
894 c(:,i) = beta * c(:,i)
897 c(:,i) = c(:,i) + temp * conjg(b(i,:))
902 if (beta == zero)
then
904 else if (beta /= one)
then
905 c(:,i) = beta * c(:,i)
908 c(:,i) = c(:,i) + temp * b(:,i)
914 if (beta == zero)
then
916 else if (beta /= one)
then
917 c(:,k+1:m) = beta * c(:,k+1:m)
927 module subroutine diag_mtx_mult_mtx_cmplx(lside, opb, alpha, a, b, beta, c, err)
929 logical,
intent(in) :: lside
930 integer(int32),
intent(in) :: opb
931 complex(real64) :: alpha, beta
932 complex(real64),
intent(in),
dimension(:) :: a
933 complex(real64),
intent(in),
dimension(:,:) :: b
934 complex(real64),
intent(inout),
dimension(:,:) :: c
935 class(errors),
intent(inout),
optional,
target :: err
938 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
939 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
942 integer(int32) :: i, m, n, k, nrowb, ncolb, flag
943 complex(real64) :: temp
944 class(errors),
pointer :: errmgr
945 type(errors),
target :: deferr
946 character(len = :),
allocatable :: errmsg
954 if (
present(err))
then
966 if (opb == la_transpose .or. opb == la_hermitian_transpose)
then
968 if (nrowb /= n .or. ncolb < k) flag = 5
971 if (nrowb < k .or. ncolb /= n) flag = 5
978 if (opb == la_transpose .or. opb == la_hermitian_transpose)
then
980 if (ncolb /= m .or. nrowb < k) flag = 5
983 if (nrowb /= m .or. ncolb < k) flag = 5
989 allocate(
character(len = 256) :: errmsg)
990 write(errmsg, 100)
"Input number ", flag, &
991 " is not sized correctly."
992 call errmgr%report_error(
"diag_mtx_mult_mtx_cmplx", trim(errmsg), &
999 if (beta == zero)
then
1001 else if (beta /= one)
then
1009 if (opb == la_transpose)
then
1012 if (beta == zero)
then
1014 else if (beta /= one)
then
1015 c(i,:) = beta * c(i,:)
1018 c(i,:) = c(i,:) + temp * b(:,i)
1020 else if (opb == la_hermitian_transpose)
then
1023 if (beta == zero)
then
1025 else if (beta /= one)
then
1026 c(i,:) = beta * c(i,:)
1029 c(i,:) = c(i,:) + temp * conjg(b(:,i))
1034 if (beta == zero)
then
1036 else if (beta /= one)
then
1037 c(i,:) = beta * c(i,:)
1040 c(i,:) = c(i,:) + temp * b(i,:)
1046 if (beta == zero)
then
1049 c(k+1:m,:) = beta * c(k+1:m,:)
1053 if (opb == la_transpose)
then
1056 if (beta == zero)
then
1058 else if (beta /= one)
then
1059 c(:,i) = beta * c(:,i)
1062 c(:,i) = c(:,i) + temp * b(i,:)
1064 else if (opb == la_hermitian_transpose)
then
1067 if (beta == zero)
then
1069 else if (beta /= one)
then
1070 c(:,i) = beta * c(:,i)
1073 c(:,i) = c(:,i) + temp * conjg(b(i,:))
1078 if (beta == zero)
then
1080 else if (beta /= one)
then
1081 c(:,i) = beta * c(:,i)
1084 c(:,i) = c(:,i) + temp * b(:,i)
1090 if (beta == zero)
then
1092 else if (beta /= one)
then
1093 c(:,k+1:m) = beta * c(:,k+1:m)
1103 module subroutine diag_mtx_mult_mtx2_cmplx(lside, alpha, a, b, err)
1105 logical,
intent(in) :: lside
1106 complex(real64),
intent(in) :: alpha
1107 complex(real64),
intent(in),
dimension(:) :: a
1108 complex(real64),
intent(inout),
dimension(:,:) :: b
1109 class(errors),
intent(inout),
optional,
target :: err
1112 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
1113 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
1116 integer(int32) :: i, m, n, k
1117 complex(real64) :: temp
1118 class(errors),
pointer :: errmgr
1119 type(errors),
target :: deferr
1125 if (
present(err))
then
1132 if ((lside .and. k > m) .or. (.not.lside .and. k > n))
then
1134 call errmgr%report_error(
"diag_mtx_mult_mtx2_cmplx", &
1135 "Input number 3 is not sized correctly.", &
1136 la_array_size_error)
1145 b(i,:) = temp * b(i,:)
1147 if (m > k) b(k+1:m,:) = zero
1152 b(:,i) = temp * b(:,i)
1154 if (n > k) b(:,k+1:n) = zero
1159 module subroutine diag_mtx_mult_mtx_mix(lside, opb, alpha, a, b, beta, c, err)
1161 logical,
intent(in) :: lside
1162 integer(int32),
intent(in) :: opb
1163 complex(real64) :: alpha, beta
1164 real(real64),
intent(in),
dimension(:) :: a
1165 complex(real64),
intent(in),
dimension(:,:) :: b
1166 complex(real64),
intent(inout),
dimension(:,:) :: c
1167 class(errors),
intent(inout),
optional,
target :: err
1170 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
1171 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
1174 integer(int32) :: i, m, n, k, nrowb, ncolb, flag
1175 complex(real64) :: temp
1176 class(errors),
pointer :: errmgr
1177 type(errors),
target :: deferr
1178 character(len = :),
allocatable :: errmsg
1186 if (
present(err))
then
1198 if (opb == la_transpose .or. opb == la_hermitian_transpose)
then
1200 if (nrowb /= n .or. ncolb < k) flag = 5
1203 if (nrowb < k .or. ncolb /= n) flag = 5
1210 if (opb == la_transpose .or. opb == la_hermitian_transpose)
then
1212 if (ncolb /= m .or. nrowb < k) flag = 5
1215 if (nrowb /= m .or. ncolb < k) flag = 5
1221 allocate(
character(len = 256) :: errmsg)
1222 write(errmsg, 100)
"Input number ", flag, &
1223 " is not sized correctly."
1224 call errmgr%report_error(
"diag_mtx_mult_mtx_mix", trim(errmsg), &
1225 la_array_size_error)
1230 if (alpha == 0)
then
1231 if (beta == zero)
then
1233 else if (beta /= one)
then
1241 if (opb == la_transpose)
then
1244 if (beta == zero)
then
1246 else if (beta /= one)
then
1247 c(i,:) = beta * c(i,:)
1250 c(i,:) = c(i,:) + temp * b(:,i)
1252 else if (opb == la_hermitian_transpose)
then
1255 if (beta == zero)
then
1257 else if (beta /= one)
then
1258 c(i,:) = beta * c(i,:)
1261 c(i,:) = c(i,:) + temp * conjg(b(:,i))
1266 if (beta == zero)
then
1268 else if (beta /= one)
then
1269 c(i,:) = beta * c(i,:)
1272 c(i,:) = c(i,:) + temp * b(i,:)
1278 if (beta == zero)
then
1281 c(k+1:m,:) = beta * c(k+1:m,:)
1285 if (opb == la_transpose)
then
1288 if (beta == zero)
then
1290 else if (beta /= one)
then
1291 c(:,i) = beta * c(:,i)
1294 c(:,i) = c(:,i) + temp * b(i,:)
1296 else if (opb == la_hermitian_transpose)
then
1299 if (beta == zero)
then
1301 else if (beta /= one)
then
1302 c(:,i) = beta * c(:,i)
1305 c(:,i) = c(:,i) + temp * conjg(b(i,:))
1310 if (beta == zero)
then
1312 else if (beta /= one)
then
1313 c(:,i) = beta * c(:,i)
1316 c(:,i) = c(:,i) + temp * b(:,i)
1322 if (beta == zero)
then
1324 else if (beta /= one)
then
1325 c(:,k+1:m) = beta * c(:,k+1:m)
1335 module subroutine diag_mtx_mult_mtx2_mix(lside, alpha, a, b, err)
1337 logical,
intent(in) :: lside
1338 complex(real64),
intent(in) :: alpha
1339 real(real64),
intent(in),
dimension(:) :: a
1340 complex(real64),
intent(inout),
dimension(:,:) :: b
1341 class(errors),
intent(inout),
optional,
target :: err
1344 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
1345 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
1348 integer(int32) :: i, m, n, k
1349 complex(real64) :: temp
1350 class(errors),
pointer :: errmgr
1351 type(errors),
target :: deferr
1357 if (
present(err))
then
1364 if ((lside .and. k > m) .or. (.not.lside .and. k > n))
then
1366 call errmgr%report_error(
"diag_mtx_mult_mtx2_cmplx", &
1367 "Input number 3 is not sized correctly.", &
1368 la_array_size_error)
1377 b(i,:) = temp * b(i,:)
1379 if (m > k) b(k+1:m,:) = zero
1384 b(:,i) = temp * b(:,i)
1386 if (n > k) b(:,k+1:n) = zero
1391 module subroutine diag_mtx_sparse_mult(lside, alpha, a, b, err)
1393 logical,
intent(in) :: lside
1394 real(real64),
intent(in) :: alpha
1395 real(real64),
intent(in),
dimension(:) :: a
1396 type(csr_matrix),
intent(inout) :: b
1397 class(errors),
intent(inout),
optional,
target :: err
1400 integer(int32) :: ii, k, k1, k2, nrow
1401 real(real64) :: scal
1402 class(errors),
pointer :: errmgr
1403 type(errors),
target :: deferr
1407 if (
present(err))
then
1415 if (
size(a) /= nrow)
then
1416 call errmgr%report_error(
"diag_mtx_sparse_mult", &
1417 "Inner matrix dimension error.", la_array_size_error)
1421 if (
size(a) /=
size(b, 2))
then
1422 call errmgr%report_error(
"diag_mtx_sparse_mult", &
1423 "Inner matrix dimension error.", la_array_size_error)
1432 k1 = b%row_indices(ii)
1433 k2 = b%row_indices(ii+1) - 1
1434 if (alpha == 1.0d0)
then
1437 scal = alpha * a(ii)
1440 b%values(k) = b%values(k) * scal
1446 k1 = b%row_indices(ii)
1447 k2 = b%row_indices(ii+1) - 1
1448 if (alpha == 1.0d0)
then
1450 b%values(k) = b%values(k) * a(b%column_indices(k))
1454 b%values(k) = alpha * b%values(k) * a(b%column_indices(k))
1464 pure module function trace_dbl(x) result(y)
1466 real(real64),
intent(in),
dimension(:,:) :: x
1470 real(real64),
parameter :: zero = 0.0d0
1473 integer(int32) :: i, m, n, mn
1488 pure module function trace_cmplx(x) result(y)
1490 complex(real64),
intent(in),
dimension(:,:) :: x
1491 complex(real64) :: y
1494 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
1497 integer(int32) :: i, m, n, mn
1512 module function mtx_rank_dbl(a, tol, work, olwork, err) result(rnk)
1514 real(real64),
intent(inout),
dimension(:,:) :: a
1515 real(real64),
intent(in),
optional :: tol
1516 real(real64),
intent(out),
target,
optional,
dimension(:) :: work
1517 integer(int32),
intent(out),
optional :: olwork
1518 class(errors),
intent(inout),
optional,
target :: err
1519 integer(int32) :: rnk
1522 integer(int32) :: i, m, n, mn, istat, lwork, flag
1523 real(real64),
pointer,
dimension(:) :: wptr, s, w
1524 real(real64),
allocatable,
target,
dimension(:) :: wrk
1525 real(real64) :: t, tref, smlnum
1526 real(real64),
dimension(1) :: dummy, temp
1527 class(errors),
pointer :: errmgr
1528 type(errors),
target :: deferr
1529 character(len = :),
allocatable :: errmsg
1537 if (
present(err))
then
1545 call dgesvd(
'N',
'N', m, n, a, m, dummy, dummy, m, dummy, n, temp, &
1547 lwork = int(temp(1), int32) + mn
1548 if (
present(olwork))
then
1554 if (
present(work))
then
1555 if (
size(work) < lwork)
then
1557 call errmgr%report_error(
"mtx_rank", &
1558 "Incorrectly sized input array WORK, argument 5.", &
1559 la_array_size_error)
1562 wptr => work(1:lwork)
1564 allocate(wrk(lwork), stat = istat)
1565 if (istat /= 0)
then
1567 call errmgr%report_error(
"mtx_rank", &
1568 "Insufficient memory available.", &
1569 la_out_of_memory_error)
1575 w => wptr(mn+1:lwork)
1578 call dgesvd(
'N',
'N', m, n, a, m, s, dummy, m, dummy, n, w, &
1581 allocate(
character(len = 256) :: errmsg)
1582 write(errmsg, 100) flag,
" superdiagonals could not " // &
1583 "converge to zero as part of the QR iteration process."
1584 call errmgr%report_warning(
"mtx_rank", errmsg, la_convergence_error)
1589 tref = max(m, n) * epsilon(t) * s(1)
1590 if (
present(tol))
then
1595 if (t < smlnum)
then
1616 module function mtx_rank_cmplx(a, tol, work, olwork, rwork, err) result(rnk)
1618 complex(real64),
intent(inout),
dimension(:,:) :: a
1619 real(real64),
intent(in),
optional :: tol
1620 complex(real64),
intent(out),
target,
optional,
dimension(:) :: work
1621 integer(int32),
intent(out),
optional :: olwork
1622 real(real64),
intent(out),
target,
optional,
dimension(:) :: rwork
1623 class(errors),
intent(inout),
optional,
target :: err
1624 integer(int32) :: rnk
1628 function dlamch(cmach)
result(x)
1629 use,
intrinsic :: iso_fortran_env, only : real64
1630 character,
intent(in) :: cmach
1636 integer(int32) :: i, m, n, mn, istat, lwork, flag, lrwork
1637 real(real64),
pointer,
dimension(:) :: s, rwptr, rw
1638 real(real64),
allocatable,
target,
dimension(:) :: rwrk
1639 complex(real64),
allocatable,
target,
dimension(:) :: wrk
1640 complex(real64),
pointer,
dimension(:) :: wptr
1641 real(real64) :: t, tref, smlnum
1642 real(real64),
dimension(1) :: dummy
1643 complex(real64),
dimension(1) :: cdummy, temp
1644 class(errors),
pointer :: errmgr
1645 type(errors),
target :: deferr
1646 character(len = :),
allocatable :: errmsg
1655 if (
present(err))
then
1662 call zgesvd(
'N',
'N', m, n, a, m, dummy, cdummy, m, cdummy, n, temp, &
1664 lwork = int(temp(1), int32)
1665 if (
present(olwork))
then
1671 if (
present(work))
then
1672 if (
size(work) < lwork)
then
1674 call errmgr%report_error(
"mtx_rank_cmplx", &
1675 "Incorrectly sized input array WORK, argument 5.", &
1676 la_array_size_error)
1679 wptr => work(1:lwork)
1681 allocate(wrk(lwork), stat = istat)
1682 if (istat /= 0)
then
1684 call errmgr%report_error(
"mtx_rank_cmplx", &
1685 "Insufficient memory available.", &
1686 la_out_of_memory_error)
1692 if (
present(rwork))
then
1693 if (
size(rwork) < lrwork)
then
1695 call errmgr%report_error(
"mtx_rank_cmplx", &
1696 "Incorrectly sized input array RWORK.", &
1697 la_array_size_error)
1700 rwptr => rwork(1:lrwork)
1702 allocate(rwrk(lrwork), stat = istat)
1703 if (istat /= 0)
then
1708 rw => rwptr(mn+1:lrwork)
1711 call zgesvd(
'N',
'N', m, n, a, m, s, cdummy, m, cdummy, n, wptr, &
1712 lwork - mn, rw, flag)
1714 allocate(
character(len = 256) :: errmsg)
1715 write(errmsg, 100) flag,
" superdiagonals could not " // &
1716 "converge to zero as part of the QR iteration process."
1717 call errmgr%report_warning(
"mtx_rank_cmplx", errmsg, la_convergence_error)
1722 tref = max(m, n) * epsilon(t) * s(1)
1723 if (
present(tol))
then
1728 if (t < smlnum)
then
1749 module function det_dbl(a, iwork, err) result(x)
1751 real(real64),
intent(inout),
dimension(:,:) :: a
1752 integer(int32),
intent(out),
target,
optional,
dimension(:) :: iwork
1753 class(errors),
intent(inout),
optional,
target :: err
1757 real(real64),
parameter :: zero = 0.0d0
1758 real(real64),
parameter :: one = 1.0d0
1759 real(real64),
parameter :: ten = 1.0d1
1760 real(real64),
parameter :: p1 = 1.0d-1
1763 integer(int32) :: i, ep, n, istat, flag
1764 integer(int32),
pointer,
dimension(:) :: ipvt
1765 integer(int32),
allocatable,
target,
dimension(:) :: iwrk
1766 real(real64) :: temp
1767 class(errors),
pointer :: errmgr
1768 type(errors),
target :: deferr
1773 if (
present(err))
then
1780 if (
size(a, 2) /= n)
then
1781 call errmgr%report_error(
"det", &
1782 "The supplied matrix must be square.", la_array_size_error)
1787 if (
present(iwork))
then
1788 if (
size(iwork) < n)
then
1790 call errmgr%report_error(
"det", &
1791 "Incorrectly sized input array IWORK, argument 2.", &
1792 la_array_size_error)
1797 allocate(iwrk(n), stat = istat)
1798 if (istat /= 0)
then
1800 call errmgr%report_error(
"det", &
1801 "Insufficient memory available.", &
1802 la_out_of_memory_error)
1809 call dgetrf(n, n, a, n, ipvt, flag)
1820 if (ipvt(i) /= i) temp = -temp
1822 temp = a(i,i) * temp
1823 if (temp == zero)
then
1828 do while (abs(temp) < one)
1833 do while (abs(temp) > ten)
1842 module function det_cmplx(a, iwork, err) result(x)
1844 complex(real64),
intent(inout),
dimension(:,:) :: a
1845 integer(int32),
intent(out),
target,
optional,
dimension(:) :: iwork
1846 class(errors),
intent(inout),
optional,
target :: err
1847 complex(real64) :: x
1850 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
1851 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
1852 complex(real64),
parameter :: ten = (1.0d1, 0.0d0)
1853 complex(real64),
parameter :: p1 = (1.0d-1, 0.0d0)
1854 real(real64),
parameter :: real_one = 1.0d0
1855 real(real64),
parameter :: real_ten = 1.0d1
1858 integer(int32) :: i, ep, n, istat, flag
1859 integer(int32),
pointer,
dimension(:) :: ipvt
1860 integer(int32),
allocatable,
target,
dimension(:) :: iwrk
1861 complex(real64) :: temp
1862 class(errors),
pointer :: errmgr
1863 type(errors),
target :: deferr
1868 if (
present(err))
then
1875 if (
size(a, 2) /= n)
then
1876 call errmgr%report_error(
"det_cmplx", &
1877 "The supplied matrix must be square.", la_array_size_error)
1882 if (
present(iwork))
then
1883 if (
size(iwork) < n)
then
1885 call errmgr%report_error(
"det_cmplx", &
1886 "Incorrectly sized input array IWORK, argument 2.", &
1887 la_array_size_error)
1892 allocate(iwrk(n), stat = istat)
1893 if (istat /= 0)
then
1895 call errmgr%report_error(
"det_cmplx", &
1896 "Insufficient memory available.", &
1897 la_out_of_memory_error)
1904 call zgetrf(n, n, a, n, ipvt, flag)
1915 if (ipvt(i) /= i) temp = -temp
1917 temp = a(i,i) * temp
1918 if (temp == zero)
then
1923 do while (abs(temp) < real_one)
1928 do while (abs(temp) > real_ten)
1939 module subroutine swap_dbl(x, y, err)
1941 real(real64),
intent(inout),
dimension(:) :: x, y
1942 class(errors),
intent(inout),
optional,
target :: err
1945 integer(int32) :: i, n
1946 real(real64) :: temp
1947 class(errors),
pointer :: errmgr
1948 type(errors),
target :: deferr
1952 if (
present(err))
then
1959 if (
size(y) /= n)
then
1960 call errmgr%report_error(
"swap", &
1961 "The input arrays are not the same size.", &
1962 la_array_size_error)
1975 module subroutine swap_cmplx(x, y, err)
1977 complex(real64),
intent(inout),
dimension(:) :: x, y
1978 class(errors),
intent(inout),
optional,
target :: err
1981 integer(int32) :: i, n
1982 complex(real64) :: temp
1983 class(errors),
pointer :: errmgr
1984 type(errors),
target :: deferr
1988 if (
present(err))
then
1995 if (
size(y) /= n)
then
1996 call errmgr%report_error(
"swap_cmplx", &
1997 "The input arrays are not the same size.", &
1998 la_array_size_error)
2013 module subroutine recip_mult_array_dbl(a, x)
2015 real(real64),
intent(in) :: a
2016 real(real64),
intent(inout),
dimension(:) :: x
2020 function dlamch(cmach)
result(x)
2021 use,
intrinsic :: iso_fortran_env, only : real64
2022 character,
intent(in) :: cmach
2028 real(real64),
parameter :: zero = 0.0d0
2029 real(real64),
parameter :: one = 1.0d0
2030 real(real64),
parameter :: twotho = 2.0d3
2034 real(real64) :: bignum, cden, cden1, cnum, cnum1, mul, smlnum
2038 bignum = one / smlnum
2039 if (log10(bignum) > twotho)
then
2040 smlnum = sqrt(smlnum)
2041 bignum = sqrt(bignum)
2050 cden1 = cden * smlnum
2051 cnum1 = cnum / bignum
2052 if (abs(cden1) > abs(cnum) .and. cnum /= zero)
then
2056 else if (abs(cnum1) > abs(cden))
then
2076 module subroutine tri_mtx_mult_dbl(upper, alpha, a, beta, b, err)
2078 logical,
intent(in) :: upper
2079 real(real64),
intent(in) :: alpha, beta
2080 real(real64),
intent(in),
dimension(:,:) :: a
2081 real(real64),
intent(inout),
dimension(:,:) :: b
2082 class(errors),
intent(inout),
optional,
target :: err
2085 real(real64),
parameter :: zero = 0.0d0
2088 integer(int32) :: i, j, k, n, d1, d2, flag
2089 real(real64) :: temp
2090 class(errors),
pointer :: errmgr
2091 type(errors),
target :: deferr
2092 character(len = :),
allocatable :: errmsg
2098 if (
present(err))
then
2106 if (
size(a, 2) /= n)
then
2109 else if (
size(b, 1) /= n .or.
size(b, 2) /= n)
then
2116 allocate(
character(len = 256) :: errmsg)
2117 write(errmsg, 100)
"The matrix at input ", flag, &
2118 " was not sized appropriately. A matrix of ", n,
"-by-", n, &
2119 "was expected, but a matrix of ", d1,
"-by-", d2,
" was found."
2120 call errmgr%report_error(
"tri_mtx_mult_dbl", trim(errmsg), &
2121 la_array_size_error)
2128 if (beta == zero)
then
2133 temp = temp + a(k,i) * a(k,j)
2137 if (i /= j) b(j,i) = temp
2145 temp = temp + a(k,i) * a(k,j)
2148 b(i,j) = temp + beta * b(i,j)
2149 if (i /= j) b(j,i) = temp + beta * b(j,i)
2155 if (beta == zero)
then
2160 temp = temp + a(i,k) * a(j,k)
2164 if (i /= j) b(j,i) = temp
2172 temp = temp + a(i,k) * a(j,k)
2175 b(i,j) = temp + beta * b(i,j)
2176 if (i /= j) b(j,i) = temp + beta * b(j,i)
2183100
format(a, i0, a, i0, a, i0, a, i0, a, i0, a)
2187 module subroutine tri_mtx_mult_cmplx(upper, alpha, a, beta, b, err)
2189 logical,
intent(in) :: upper
2190 complex(real64),
intent(in) :: alpha, beta
2191 complex(real64),
intent(in),
dimension(:,:) :: a
2192 complex(real64),
intent(inout),
dimension(:,:) :: b
2193 class(errors),
intent(inout),
optional,
target :: err
2196 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
2199 integer(int32) :: i, j, k, n, d1, d2, flag
2200 complex(real64) :: temp
2201 class(errors),
pointer :: errmgr
2202 type(errors),
target :: deferr
2203 character(len = :),
allocatable :: errmsg
2209 if (
present(err))
then
2217 if (
size(a, 2) /= n)
then
2220 else if (
size(b, 1) /= n .or.
size(b, 2) /= n)
then
2227 allocate(
character(len = 256) :: errmsg)
2228 write(errmsg, 100)
"The matrix at input ", flag, &
2229 " was not sized appropriately. A matrix of ", n,
"-by-", n, &
2230 "was expected, but a matrix of ", d1,
"-by-", d2,
" was found."
2231 call errmgr%report_error(
"tri_mtx_mult_cmplx", trim(errmsg), &
2232 la_array_size_error)
2239 if (beta == zero)
then
2244 temp = temp + a(k,i) * a(k,j)
2248 if (i /= j) b(j,i) = temp
2256 temp = temp + a(k,i) * a(k,j)
2259 b(i,j) = temp + beta * b(i,j)
2260 if (i /= j) b(j,i) = temp + beta * b(j,i)
2266 if (beta == zero)
then
2271 temp = temp + a(i,k) * a(j,k)
2275 if (i /= j) b(j,i) = temp
2283 temp = temp + a(i,k) * a(j,k)
2286 b(i,j) = temp + beta * b(i,j)
2287 if (i /= j) b(j,i) = temp + beta * b(j,i)
2294100
format(a, i0, a, i0, a, i0, a, i0, a, i0, a)
2300 module subroutine band_mtx_vec_mult_dbl(trans, kl, ku, alpha, a, x, beta, &
2303 logical,
intent(in) :: trans
2304 integer(int32),
intent(in) :: kl, ku
2305 real(real64),
intent(in) :: alpha, beta
2306 real(real64),
intent(in),
dimension(:,:) :: a
2307 real(real64),
intent(in),
dimension(:) :: x
2308 real(real64),
intent(inout),
dimension(:) :: y
2309 class(errors),
intent(inout),
optional,
target :: err
2312 integer(int32) :: m, n
2313 class(errors),
pointer :: errmgr
2314 type(errors),
target :: deferr
2317 if (
present(err))
then
2331 if (kl < 0)
go to 10
2332 if (ku < 0)
go to 20
2333 if (
size(a, 1) /= kl + ku + 1)
go to 30
2334 if (
size(a, 2) /= n)
go to 30
2338 call dgbmv(
"T", m, n, kl, ku, alpha, a,
size(a, 1), x, 1, beta, y, 1)
2340 call dgbmv(
"N", m, n, kl, ku, alpha, a,
size(a, 1), x, 1, beta, y, 1)
2348 call errmgr%report_error(
"band_mtx_vec_mult_dbl", &
2349 "The number of subdiagonals must be at least 0.", &
2350 la_invalid_input_error)
2355 call errmgr%report_error(
"band_mtx_vec_mult_dbl", &
2356 "The number of superdiagonals must be at least 0.", &
2357 la_invalid_input_error)
2362 call errmgr%report_error(
"band_mtx_vec_mult_dbl", &
2363 "The size of matrix A is not compatible with the other vectors.", &
2364 la_array_size_error)
2369 module subroutine band_mtx_vec_mult_cmplx(trans, kl, ku, alpha, a, x, &
2372 integer(int32),
intent(in) :: trans
2373 integer(int32),
intent(in) :: kl, ku
2374 complex(real64),
intent(in) :: alpha, beta
2375 complex(real64),
intent(in),
dimension(:,:) :: a
2376 complex(real64),
intent(in),
dimension(:) :: x
2377 complex(real64),
intent(inout),
dimension(:) :: y
2378 class(errors),
intent(inout),
optional,
target :: err
2383 integer(int32) :: m, n
2384 class(errors),
pointer :: errmgr
2385 type(errors),
target :: deferr
2388 if (
present(err))
then
2393 if (trans == la_transpose)
then
2396 else if (trans == la_hermitian_transpose)
then
2412 if (kl < 0)
go to 10
2413 if (ku < 0)
go to 20
2414 if (
size(a, 1) /= kl + ku + 1)
go to 30
2415 if (
size(a, 2) /= n)
go to 30
2418 call zgbmv(op, m, n, kl, ku, alpha, a,
size(a, 1), x, 1, beta, y, 1)
2425 call errmgr%report_error(
"band_mtx_vec_mult_cmplx", &
2426 "The number of subdiagonals must be at least 0.", &
2427 la_invalid_input_error)
2432 call errmgr%report_error(
"band_mtx_vec_mult_cmplx", &
2433 "The number of superdiagonals must be at least 0.", &
2434 la_invalid_input_error)
2439 call errmgr%report_error(
"band_mtx_vec_mult_cmplx", &
2440 "The size of matrix A is not compatible with the other vectors.", &
2441 la_array_size_error)
2446 module subroutine band_to_full_mtx_dbl(kl, ku, b, f, err)
2448 integer(int32),
intent(in) :: kl, ku
2449 real(real64),
intent(in),
dimension(:,:) :: b
2450 real(real64),
intent(out),
dimension(:,:) :: f
2451 class(errors),
intent(inout),
optional,
target :: err
2454 real(real64),
parameter :: zero = 0.0d0
2457 class(errors),
pointer :: errmgr
2458 type(errors),
target :: deferr
2459 integer(int32) :: i, j, k, m, n, i1, i2
2462 if (
present(err))
then
2471 if (kl < 0)
go to 10
2472 if (ku < 0)
go to 20
2473 if (
size(b, 2) /= n)
go to 30
2474 if (
size(b, 1) /= kl + ku + 1)
go to 40
2497 call errmgr%report_error(
"band_to_full_mtx_dbl", &
2498 "The number of subdiagonals must be at least 0.", &
2499 la_invalid_input_error)
2504 call errmgr%report_error(
"band_to_full_mtx_dbl", &
2505 "The number of superdiagonals must be at least 0.", &
2506 la_invalid_input_error)
2511 call errmgr%report_error(
"band_to_full_mtx_dbl", &
2512 "The number of columns in the banded matrix does not match " // &
2513 "the number of columns in the full matrix.", &
2514 la_array_size_error)
2518 call errmgr%report_error(
"band_to_full_mtx_dbl", &
2519 "The number of rows in the banded matrix does not align with " // &
2520 "the number of sub and super-diagonals specified.", &
2521 la_array_size_error)
2526 module subroutine band_to_full_mtx_cmplx(kl, ku, b, f, err)
2528 integer(int32),
intent(in) :: kl, ku
2529 complex(real64),
intent(in),
dimension(:,:) :: b
2530 complex(real64),
intent(out),
dimension(:,:) :: f
2531 class(errors),
intent(inout),
optional,
target :: err
2534 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
2537 class(errors),
pointer :: errmgr
2538 type(errors),
target :: deferr
2539 integer(int32) :: i, j, k, m, n, i1, i2
2542 if (
present(err))
then
2551 if (kl < 0)
go to 10
2552 if (ku < 0)
go to 20
2553 if (
size(b, 2) /= n)
go to 30
2554 if (
size(b, 1) /= kl + ku + 1)
go to 40
2577 call errmgr%report_error(
"band_to_full_mtx_cmplx", &
2578 "The number of subdiagonals must be at least 0.", &
2579 la_invalid_input_error)
2584 call errmgr%report_error(
"band_to_full_mtx_cmplx", &
2585 "The number of superdiagonals must be at least 0.", &
2586 la_invalid_input_error)
2591 call errmgr%report_error(
"band_to_full_mtx_cmplx", &
2592 "The number of columns in the banded matrix does not match " // &
2593 "the number of columns in the full matrix.", &
2594 la_array_size_error)
2598 call errmgr%report_error(
"band_to_full_mtx_cmplx", &
2599 "The number of rows in the banded matrix does not align with " // &
2600 "the number of sub and super-diagonals specified.", &
2601 la_array_size_error)
2606 module subroutine band_diag_mtx_mult_dbl(left, m, kl, ku, alpha, a, b, err)
2608 logical,
intent(in) :: left
2609 integer(int32),
intent(in) :: m, kl, ku
2610 real(real64),
intent(in) :: alpha
2611 real(real64),
intent(inout),
dimension(:,:) :: a
2612 real(real64),
intent(in),
dimension(:) :: b
2613 class(errors),
intent(inout),
optional,
target :: err
2616 real(real64),
parameter :: one = 1.0d0
2619 class(errors),
pointer :: errmgr
2620 type(errors),
target :: deferr
2621 integer(int32) :: i, i1, i2, j, k, n
2622 real(real64) :: temp
2625 if (
present(err))
then
2633 if (kl < 0)
go to 10
2634 if (ku < 0)
go to 20
2636 if (
size(b) /= n)
go to 30
2638 if (
size(b) < m)
go to 30
2646 i1 = max(1, j - ku) + k
2647 i2 = min(m, j + kl) + k
2648 if (alpha == one)
then
2654 a(i,j) = a(i,j) * temp
2663 if (alpha == 1.0d0)
then
2665 a(i+k,j) = a(i+k,j) * b(i)
2669 a(i+k,j) = alpha * a(i+k,j) * b(i)
2681 call errmgr%report_error(
"band_diag_mtx_mult_dbl", &
2682 "The number of subdiagonals must be at least 0.", &
2683 la_invalid_input_error)
2688 call errmgr%report_error(
"band_diag_mtx_mult_dbl", &
2689 "The number of superdiagonals must be at least 0.", &
2690 la_invalid_input_error)
2695 call errmgr%report_error(
"band_diag_mtx_mult_dbl", &
2696 "Inner matrix dimensions do not agree.", &
2697 la_array_size_error)
2702 module subroutine band_diag_mtx_mult_cmplx(left, m, kl, ku, alpha, a, b, err)
2704 logical,
intent(in) :: left
2705 integer(int32),
intent(in) :: m, kl, ku
2706 complex(real64),
intent(in) :: alpha
2707 complex(real64),
intent(inout),
dimension(:,:) :: a
2708 complex(real64),
intent(in),
dimension(:) :: b
2709 class(errors),
intent(inout),
optional,
target :: err
2712 complex(real64),
parameter :: one = (1.0d0, 0.0d0)
2715 class(errors),
pointer :: errmgr
2716 type(errors),
target :: deferr
2717 integer(int32) :: i, i1, i2, j, k, n
2718 complex(real64) :: temp
2721 if (
present(err))
then
2729 if (kl < 0)
go to 10
2730 if (ku < 0)
go to 20
2732 if (
size(b) /= n)
go to 30
2734 if (
size(b) < m)
go to 30
2742 i1 = max(1, j - ku) + k
2743 i2 = min(m, j + kl) + k
2744 if (alpha == one)
then
2750 a(i,j) = a(i,j) * temp
2759 if (alpha == 1.0d0)
then
2761 a(i+k,j) = a(i+k,j) * b(i)
2765 a(i+k,j) = alpha * a(i+k,j) * b(i)
2777 call errmgr%report_error(
"band_diag_mtx_mult_cmplx", &
2778 "The number of subdiagonals must be at least 0.", &
2779 la_invalid_input_error)
2784 call errmgr%report_error(
"band_diag_mtx_mult_cmplx", &
2785 "The number of superdiagonals must be at least 0.", &
2786 la_invalid_input_error)
2791 call errmgr%report_error(
"band_diag_mtx_mult_cmplx", &
2792 "Inner matrix dimensions do not agree.", &
2793 la_array_size_error)
2798 module subroutine banded_to_dense_dbl(m, kl, ku, a, x, err)
2800 integer(int32),
intent(in) :: m, kl, ku
2801 real(real64),
intent(in),
dimension(:,:) :: a
2802 real(real64),
intent(out),
dimension(:,:) :: x
2803 class(errors),
intent(inout),
optional,
target :: err
2806 real(real64),
parameter :: zero = 0.0d0
2809 integer(int32) :: i, j, k, n, i1, i2
2810 class(errors),
pointer :: errmgr
2811 type(errors),
target :: deferr
2814 if (
present(err))
then
2822 if (kl < 0 .or. ku < 0)
then
2823 call errmgr%report_error(
"banded_to_dense_dbl", &
2824 "The bandwidth dimensions must not be negative-valued.", &
2825 la_invalid_input_error)
2828 if (
size(a, 1) /= kl + ku + 1)
then
2829 call errmgr%report_error(
"banded_to_dense_dbl",
"The size of " // &
2830 "the input matrix does not match the specified bandwidth.", &
2831 la_matrix_format_error)
2834 if (
size(x, 1) /= m .or.
size(x, 2) /= n)
then
2835 call errmgr%report_error(
"banded_to_dense_dbl", &
2836 "The output matrix dimensions are not correct.", &
2837 la_array_size_error)
2848 x(i, j) = a(k + i, j)
2855 module subroutine banded_to_dense_cmplx(m, kl, ku, a, x, err)
2857 integer(int32),
intent(in) :: m, kl, ku
2858 complex(real64),
intent(in),
dimension(:,:) :: a
2859 complex(real64),
intent(out),
dimension(:,:) :: x
2860 class(errors),
intent(inout),
optional,
target :: err
2863 complex(real64),
parameter :: zero = (0.0d0, 0.0d0)
2866 integer(int32) :: i, j, k, n, i1, i2
2867 class(errors),
pointer :: errmgr
2868 type(errors),
target :: deferr
2871 if (
present(err))
then
2879 if (kl < 0 .or. ku < 0)
then
2880 call errmgr%report_error(
"banded_to_dense_cmplx", &
2881 "The bandwidth dimensions must not be negative-valued.", &
2882 la_invalid_input_error)
2885 if (
size(a, 1) /= kl + ku + 1)
then
2886 call errmgr%report_error(
"banded_to_dense_cmplx",
"The size of " // &
2887 "the input matrix does not match the specified bandwidth.", &
2888 la_matrix_format_error)
2891 if (
size(x, 1) /= m .or.
size(x, 2) /= n)
then
2892 call errmgr%report_error(
"banded_to_dense_cmplx", &
2893 "The output matrix dimensions are not correct.", &
2894 la_array_size_error)
2905 x(i, j) = a(k + i, j)
2912 module subroutine dense_to_banded_dbl(a, kl, ku, x, err)
2914 real(real64),
intent(in),
dimension(:,:) :: a
2915 integer(int32),
intent(in) :: kl, ku
2916 real(real64),
intent(out),
dimension(:,:) :: x
2917 class(errors),
intent(inout),
optional,
target :: err
2920 integer(int32) :: i, j, k, m, n, mm, flag
2921 class(errors),
pointer :: errmgr
2922 type(errors),
target :: deferr
2925 if (
present(err))
then
2935 if (kl < 0 .or. ku < 0)
then
2936 call errmgr%report_error(
"dense_to_banded_dbl", &
2937 "The bandwidth dimensions must not be negative-valued.", &
2938 la_invalid_input_error)
2941 if (
size(x, 1) /= mm .or.
size(x, 2) /= n)
then
2942 call errmgr%report_error(
"dense_to_banded_dbl", &
2943 "The output matrix dimensions are not correct.", &
2944 la_array_size_error)
2951 do i = max(1, j - ku), min(m, j + kl)
2952 x(k + i, j) = a(i,j)
2958 module subroutine dense_to_banded_cmplx(a, kl, ku, x, err)
2960 complex(real64),
intent(in),
dimension(:,:) :: a
2961 integer(int32),
intent(in) :: kl, ku
2962 complex(real64),
intent(out),
dimension(:,:) :: x
2963 class(errors),
intent(inout),
optional,
target :: err
2966 integer(int32) :: i, j, k, m, n, mm, flag
2967 class(errors),
pointer :: errmgr
2968 type(errors),
target :: deferr
2971 if (
present(err))
then
2981 if (kl < 0 .or. ku < 0)
then
2982 call errmgr%report_error(
"dense_to_banded_cmplx", &
2983 "The bandwidth dimensions must not be negative-valued.", &
2984 la_invalid_input_error)
2987 if (
size(x, 1) /= mm .or.
size(x, 2) /= n)
then
2988 call errmgr%report_error(
"dense_to_banded_cmplx", &
2989 "The output matrix dimensions are not correct.", &
2990 la_array_size_error)
2997 do i = max(1, j - ku), min(m, j + kl)
2998 x(k + i, j) = a(i,j)
3004 module subroutine extract_diagonal_dbl(a, diag, err)
3006 real(real64),
intent(in),
dimension(:,:) :: a
3007 real(real64),
intent(out),
dimension(:) :: diag
3008 class(errors),
intent(inout),
optional,
target :: err
3011 integer(int32) :: i, m, n, mn
3012 class(errors),
pointer :: errmgr
3013 type(errors),
target :: deferr
3016 if (
present(err))
then
3026 if (
size(diag) /= mn)
then
3027 call errmgr%report_error(
"extract_diagonal_dbl", &
3028 "The is expected to have MIN(M, N) elements.", &
3029 la_array_size_error)
3040 module subroutine extract_diagonal_cmplx(a, diag, err)
3042 complex(real64),
intent(in),
dimension(:,:) :: a
3043 complex(real64),
intent(out),
dimension(:) :: diag
3044 class(errors),
intent(inout),
optional,
target :: err
3047 integer(int32) :: i, m, n, mn
3048 class(errors),
pointer :: errmgr
3049 type(errors),
target :: deferr
3052 if (
present(err))
then
3062 if (
size(diag) /= mn)
then
3063 call errmgr%report_error(
"extract_diagonal_cmplx", &
3064 "The is expected to have MIN(M, N) elements.", &
3065 la_array_size_error)
A module providing explicit interfaces to BLAS routines.
Provides a set of common linear algebra routines.