24#include "../base/base_uses.f90"
29 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'mathlib'
30 REAL(KIND=
dp),
PARAMETER :: eps_geo = 1.0e-6_dp
71 MODULE PROCEDURE det_3x3_1, det_3x3_2
75 MODULE PROCEDURE invert_matrix_d, invert_matrix_z
79 MODULE PROCEDURE set_diag_scalar_d, set_diag_scalar_z
83 MODULE PROCEDURE swap_scalar, swap_vector
87 MODULE PROCEDURE unit_matrix_d, unit_matrix_z
91 MODULE PROCEDURE zgemm_square_2, zgemm_square_3, dgemm_square_2, dgemm_square_3
108 REAL(kind=
dp) :: x, a, b
112 REAL(kind=
dp) :: u, u2, u3
115 IF (x < a .OR. x > b)
THEN
136 fx = 1._dp - 10._dp*u3 + 15._dp*u2*u2 - 6._dp*u2*u3
139 fx = -30._dp*u2 + 60._dp*u*u2 - 30._dp*u2*u2
143 fx = -60._dp*u + 180._dp*u2 - 120._dp*u*u2
146 cpabort(
'order not defined')
161 CHARACTER(LEN=32) :: buffer
169 IF (index(buffer,
"N") /= 0 .OR. index(buffer,
"n") /= 0)
abnormal_value = .true.
183 PURE FUNCTION angle(a, b)
RESULT(angle_ab)
184 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: a, b
185 REAL(kind=
dp) :: angle_ab
187 REAL(kind=
dp) :: length_of_a, length_of_b
188 REAL(kind=
dp),
DIMENSION(SIZE(a, 1)) :: a_norm, b_norm
190 length_of_a = norm2(a)
191 length_of_b = norm2(b)
193 IF ((length_of_a > eps_geo) .AND. (length_of_b > eps_geo))
THEN
194 a_norm(:) = a(:)/length_of_a
195 b_norm(:) = b(:)/length_of_b
196 angle_ab = acos(min(max(dot_product(a_norm, b_norm), -1.0_dp), 1.0_dp))
214 INTEGER,
INTENT(IN) :: n, k
215 REAL(kind=
dp) :: n_over_k
217 IF ((k >= 0) .AND. (k <= n))
THEN
238 REAL(kind=
dp),
INTENT(IN) :: z
239 INTEGER,
INTENT(IN) :: k
240 REAL(kind=
dp) :: z_over_k
247 z_over_k = z_over_k*(z - i + 1)/real(i,
dp)
263 INTEGER,
INTENT(IN) :: n
264 INTEGER,
DIMENSION(:),
INTENT(IN) :: k
268 REAL(kind=
dp) :: denom
270 IF (all(k >= 0) .AND. sum(k) == n)
THEN
273 denom = denom*
fac(k(i))
294 REAL(kind=
dp),
INTENT(IN) :: phi
295 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: a
296 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(OUT) :: rotmat
298 REAL(kind=
dp) :: cosp, cost, length_of_a, sinp
299 REAL(kind=
dp),
DIMENSION(3) :: d
301 length_of_a = sqrt(a(1)*a(1) + a(2)*a(2) + a(3)*a(3))
303 IF (length_of_a > eps_geo)
THEN
305 d(:) = a(:)/length_of_a
311 rotmat(1, 1) = d(1)*d(1)*cost + cosp
312 rotmat(1, 2) = d(1)*d(2)*cost - d(3)*sinp
313 rotmat(1, 3) = d(1)*d(3)*cost + d(2)*sinp
314 rotmat(2, 1) = d(2)*d(1)*cost + d(3)*sinp
315 rotmat(2, 2) = d(2)*d(2)*cost + cosp
316 rotmat(2, 3) = d(2)*d(3)*cost - d(1)*sinp
317 rotmat(3, 1) = d(3)*d(1)*cost - d(2)*sinp
318 rotmat(3, 2) = d(3)*d(2)*cost + d(1)*sinp
319 rotmat(3, 3) = d(3)*d(3)*cost + cosp
334 PURE FUNCTION det_3x3_1(a)
RESULT(det_a)
335 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: a
336 REAL(kind=
dp) :: det_a
338 det_a = a(1, 1)*(a(2, 2)*a(3, 3) - a(2, 3)*a(3, 2)) + &
339 a(1, 2)*(a(2, 3)*a(3, 1) - a(2, 1)*a(3, 3)) + &
340 a(1, 3)*(a(2, 1)*a(3, 2) - a(2, 2)*a(3, 1))
342 END FUNCTION det_3x3_1
354 PURE FUNCTION det_3x3_2(a1, a2, a3)
RESULT(det_a)
355 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: a1, a2, a3
356 REAL(kind=
dp) :: det_a
358 det_a = a1(1)*(a2(2)*a3(3) - a3(2)*a2(3)) + &
359 a2(1)*(a3(2)*a1(3) - a1(2)*a3(3)) + &
360 a3(1)*(a1(2)*a2(3) - a2(2)*a1(3))
362 END FUNCTION det_3x3_2
381 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: a
382 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: eigval
383 LOGICAL,
INTENT(IN),
OPTIONAL :: dac
385 CHARACTER(len=*),
PARAMETER :: routinen =
'diamat_all'
387 INTEGER :: handle, info, liwork, lwork, n, nb
388 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iwork
389 INTEGER,
EXTERNAL :: ilaenv
390 LOGICAL :: divide_and_conquer
391 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work
393 EXTERNAL dsyev, dsyevd
395 CALL timeset(routinen, handle)
401 IF (
SIZE(a, 2) /= n)
THEN
402 cpabort(
"Check the size of matrix a (parameter #1)")
406 IF (
SIZE(eigval) /= n)
THEN
407 cpabort(
"The dimension of vector eigval is too small")
412 IF (
PRESENT(dac))
THEN
413 divide_and_conquer = dac
415 divide_and_conquer = .false.
420 IF (divide_and_conquer)
THEN
421 lwork = 2*n**2 + 6*n + 1
424 nb = ilaenv(1,
"DSYTRD",
"U", n, -1, -1, -1)
430 ALLOCATE (work(lwork))
431 IF (divide_and_conquer)
THEN
432 ALLOCATE (iwork(liwork))
438 IF (divide_and_conquer)
THEN
439 CALL dsyevd(
"V",
"U", n, a, n, eigval, work, lwork, iwork, liwork, info)
441 CALL dsyev(
"V",
"U", n, a, n, eigval, work, lwork, info)
445 IF (divide_and_conquer)
THEN
446 cpabort(
"The matrix diagonalization with dsyevd failed")
448 cpabort(
"The matrix diagonalization with dsyev failed")
455 IF (divide_and_conquer)
THEN
459 CALL timestop(handle)
476 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: ab, bc, cd
477 REAL(kind=
dp) :: dihedral_angle_abcd
479 REAL(kind=
dp) :: det_abcd
480 REAL(kind=
dp),
DIMENSION(3) :: abc, bcd
487 det_abcd =
det_3x3(abc, bcd, -bc)
488 dihedral_angle_abcd = sign(1.0_dp, det_abcd)*
angle(abc, bcd)
501 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
503 DIMENSION(MIN(SIZE(a, 1), SIZE(a, 2))) :: a_diag
507 n = min(
SIZE(a, 1),
SIZE(a, 2))
524 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: a
525 REAL(kind=
dp),
DIMENSION(3, 3) :: a_inv
527 REAL(kind=
dp) :: det_a
531 a_inv(1, 1) = (a(2, 2)*a(3, 3) - a(3, 2)*a(2, 3))*det_a
532 a_inv(2, 1) = (a(2, 3)*a(3, 1) - a(3, 3)*a(2, 1))*det_a
533 a_inv(3, 1) = (a(2, 1)*a(3, 2) - a(3, 1)*a(2, 2))*det_a
535 a_inv(1, 2) = (a(1, 3)*a(3, 2) - a(3, 3)*a(1, 2))*det_a
536 a_inv(2, 2) = (a(1, 1)*a(3, 3) - a(3, 1)*a(1, 3))*det_a
537 a_inv(3, 2) = (a(1, 2)*a(3, 1) - a(3, 2)*a(1, 1))*det_a
539 a_inv(1, 3) = (a(1, 2)*a(2, 3) - a(2, 2)*a(1, 3))*det_a
540 a_inv(2, 3) = (a(1, 3)*a(2, 1) - a(2, 3)*a(1, 1))*det_a
541 a_inv(3, 3) = (a(1, 1)*a(2, 2) - a(2, 1)*a(1, 2))*det_a
551 REAL(kind=
dp),
INTENT(INOUT) :: a(:, :)
552 INTEGER,
INTENT(OUT) :: info
554 CHARACTER(LEN=*),
PARAMETER :: routinen =
'invmat'
556 INTEGER :: handle, lwork, n
557 INTEGER,
ALLOCATABLE :: ipiv(:)
558 REAL(kind=
dp),
ALLOCATABLE :: work(:)
560 CALL timeset(routinen, handle)
565 ALLOCATE (work(lwork))
569 CALL dgetrf(n, n, a, n, ipiv, info)
571 CALL dgetri(n, a, n, ipiv, work, lwork, info)
573 DEALLOCATE (ipiv, work)
575 CALL timestop(handle)
588 REAL(kind=
dp),
INTENT(INOUT) :: a(:, :)
589 LOGICAL,
INTENT(IN),
OPTIONAL :: potrf
590 CHARACTER(LEN=1),
INTENT(IN),
OPTIONAL :: uplo
592 CHARACTER(LEN=*),
PARAMETER :: routinen =
'invmat_symm'
594 CHARACTER(LEN=1) :: myuplo
595 INTEGER :: handle, info, n
598 CALL timeset(routinen, handle)
601 IF (
PRESENT(potrf)) do_potrf = potrf
604 IF (
PRESENT(uplo)) myuplo = uplo
611 CALL dpotrf(myuplo, n, a, n, info)
612 IF (info /= 0) cpabort(
"DPOTRF failed")
616 CALL dpotri(myuplo, n, a, n, info)
617 IF (info /= 0) cpabort(
"Matrix inversion failed")
620 IF ((myuplo ==
"U") .OR. (myuplo ==
"u"))
THEN
626 CALL timestop(handle)
652 SUBROUTINE invert_matrix_d(a, a_inverse, eval_error, option, improve)
653 REAL(KIND=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
654 REAL(KIND=
dp),
DIMENSION(:, :),
INTENT(OUT) :: a_inverse
655 REAL(KIND=
dp),
INTENT(OUT) :: eval_error
656 CHARACTER(LEN=1),
INTENT(IN),
OPTIONAL :: option
657 LOGICAL,
INTENT(IN),
OPTIONAL :: improve
659 CHARACTER(LEN=1) :: norm, trans
660 CHARACTER(LEN=default_string_length) :: message
661 INTEGER :: info, iter, n
662 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipiv, iwork
663 LOGICAL :: do_improve
664 REAL(KIND=
dp) :: a_norm, old_eval_error, r_cond
665 REAL(KIND=
dp),
ALLOCATABLE,
DIMENSION(:) :: berr, ferr, work
666 REAL(KIND=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: a_lu, b
667 REAL(KIND=
dp),
EXTERNAL :: dlange
669 EXTERNAL dgecon, dgerfs, dgetrf, dgetrs
672 IF (
PRESENT(option))
THEN
678 IF (
PRESENT(improve))
THEN
689 cpabort(
"Matrix to be inverted of zero size")
692 IF (n /=
SIZE(a, 2))
THEN
693 cpabort(
"Check the array bounds of parameter #1")
696 IF ((n /=
SIZE(a_inverse, 1)) .OR. &
697 (n /=
SIZE(a_inverse, 2)))
THEN
698 cpabort(
"Check the array bounds of parameter #2")
702 ALLOCATE (a_lu(n, n))
710 a_lu(1:n, 1:n) = a(1:n, 1:n)
713 CALL dgetrf(n, n, a_lu, n, ipiv, info)
716 cpabort(
"The LU factorization in dgetrf failed")
721 IF (trans ==
"N")
THEN
727 a_norm = dlange(norm, n, n, a, n, work)
731 CALL dgecon(norm, n, a_lu, n, a_norm, r_cond, work, iwork, info)
734 cpabort(
"The computation of the condition number in dgecon failed")
737 IF (r_cond < epsilon(0.0_dp))
THEN
738 WRITE (message,
"(A,ES10.3)")
"R_COND =", r_cond
739 CALL cp_abort(__location__, &
740 "Bad condition number "//trim(message)//
" (smaller than the machine "// &
741 "working precision)")
748 CALL dgetrs(trans, n, n, a_lu, n, ipiv, a_inverse, n, info)
751 cpabort(
"Solving the system of linear equations in dgetrs failed")
762 CALL dgerfs(trans, n, n, a, n, a_lu, n, ipiv, b, n, a_inverse, n, ferr, berr, &
766 cpabort(
"Improving the computed solution in dgerfs failed")
769 old_eval_error = eval_error
770 eval_error = maxval(ferr)
772 IF (abs(eval_error - old_eval_error) <= epsilon(1.0_dp))
EXIT
786 END SUBROUTINE invert_matrix_d
808 SUBROUTINE invert_matrix_z(a, a_inverse, eval_error, option)
809 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(IN) :: a
810 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(OUT) :: a_inverse
811 REAL(KIND=
dp),
INTENT(OUT) :: eval_error
812 CHARACTER(LEN=1),
INTENT(IN),
OPTIONAL :: option
814 CHARACTER(LEN=1) :: norm, trans
815 CHARACTER(LEN=default_string_length) :: message
816 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:) :: work
817 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: a_lu, b
818 INTEGER :: info, iter, n
819 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipiv
820 REAL(KIND=
dp) :: a_norm, old_eval_error, r_cond
821 REAL(KIND=
dp),
ALLOCATABLE,
DIMENSION(:) :: berr, ferr, rwork
822 REAL(KIND=
dp),
EXTERNAL :: zlange
824 EXTERNAL zgecon, zgerfs, zgetrf, zgetrs
827 IF (
PRESENT(option))
THEN
838 cpabort(
"Matrix to be inverted of zero size")
841 IF (n /=
SIZE(a, 2))
THEN
842 cpabort(
"Check the array bounds of parameter #1")
845 IF ((n /=
SIZE(a_inverse, 1)) .OR. &
846 (n /=
SIZE(a_inverse, 2)))
THEN
847 cpabort(
"Check the array bounds of parameter #2")
851 ALLOCATE (a_lu(n, n))
856 ALLOCATE (rwork(2*n))
859 a_lu(1:n, 1:n) = a(1:n, 1:n)
862 CALL zgetrf(n, n, a_lu, n, ipiv, info)
865 cpabort(
"The LU factorization in dgetrf failed")
870 IF (trans ==
"N")
THEN
876 a_norm = zlange(norm, n, n, a, n, work)
880 CALL zgecon(norm, n, a_lu, n, a_norm, r_cond, work, rwork, info)
883 cpabort(
"The computation of the condition number in dgecon failed")
886 IF (r_cond < epsilon(0.0_dp))
THEN
887 WRITE (message,
"(A,ES10.3)")
"R_COND =", r_cond
888 CALL cp_abort(__location__, &
889 "Bad condition number "//trim(message)//
" (smaller than the machine "// &
890 "working precision)")
897 CALL zgetrs(trans, n, n, a_lu, n, ipiv, a_inverse, n, info)
900 cpabort(
"Solving the system of linear equations in dgetrs failed")
910 CALL zgerfs(trans, n, n, a, n, a_lu, n, ipiv, b, n, a_inverse, n, ferr, berr, &
914 cpabort(
"Improving the computed solution in dgerfs failed")
917 old_eval_error = eval_error
918 eval_error = maxval(ferr)
920 IF (abs(eval_error - old_eval_error) <= epsilon(1.0_dp))
EXIT
933 END SUBROUTINE invert_matrix_z
946 REAL(kind=
dp),
DIMENSION(:, :) :: a, a_pinverse
947 REAL(kind=
dp),
INTENT(IN) :: rskip
948 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: determinant
949 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT), &
950 OPTIONAL,
POINTER :: sval
952 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_pseudo_inverse_svd'
954 INTEGER :: handle, i, info, lwork, n
955 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iwork
956 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: sig, work
957 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: sig_plus, temp_mat, u, vt
959 CALL timeset(routinen, handle)
962 ALLOCATE (u(n, n), vt(n, n), sig(n), sig_plus(n, n), iwork(8*n), work(1), temp_mat(n, n))
969 IF (
PRESENT(determinant)) determinant = 1.0_dp
973 CALL dgesdd(
'A', n, n, a(1, 1), n, sig(1), u(1, 1), n, vt(1, 1), n, work(1), &
974 lwork, iwork(1), info)
977 cpabort(
"ERROR in DGESDD: Could not retrieve work array sizes")
981 ALLOCATE (work(lwork))
984 CALL dgesdd(
'A', n, n, a(1, 1), n, sig(1), u(1, 1), n, vt(1, 1), n, work(1), &
985 lwork, iwork(1), info)
988 cpabort(
"SVD failed")
991 IF (
PRESENT(sval))
THEN
992 cpassert(.NOT.
ASSOCIATED(sval))
999 IF (sig(i) > rskip*maxval(sig))
THEN
1000 IF (
PRESENT(determinant))
THEN
1001 determinant = determinant*sig(i)
1003 sig_plus(i, i) = 1._dp/sig(i)
1005 sig_plus(i, i) = 0.0_dp
1010 CALL dgemm(
"N",
"T", n, n, n, 1._dp, sig_plus, n, u, n, 0._dp, temp_mat, n)
1011 CALL dgemm(
"T",
"N", n, n, n, 1._dp, vt, n, temp_mat, n, 0._dp, a_pinverse, n)
1013 DEALLOCATE (u, vt, sig, iwork, work, sig_plus, temp_mat)
1015 CALL timestop(handle)
1028 REAL(kind=
dp),
DIMENSION(:, :) :: a, a_pinverse
1029 REAL(kind=
dp),
INTENT(IN) :: rskip
1031 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_pseudo_inverse_diag'
1033 INTEGER :: handle, i, info, lwork, n
1034 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eig, work
1035 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dinv, temp_mat
1037 CALL timeset(routinen, handle)
1041 ALLOCATE (dinv(n, n), eig(n), work(1), temp_mat(n, n))
1049 CALL dsyev(
'V',
'U', n, a, n, eig(1), work(1), lwork, info)
1051 cpabort(
"ERROR in DSYEV: Could not retrieve work array sizes")
1053 lwork = int(work(1))
1055 ALLOCATE (work(lwork))
1059 CALL dsyev(
'V',
'U', n, a, n, eig(1), work(1), lwork, info)
1062 cpabort(
"Matrix diagonalization failed")
1067 IF (eig(i) > rskip*maxval(eig))
THEN
1068 dinv(i, i) = 1.0_dp/eig(i)
1075 CALL dgemm(
"N",
"T", n, n, n, 1._dp, dinv, n, a, n, 0._dp, temp_mat, n)
1076 CALL dgemm(
"N",
"N", n, n, n, 1._dp, a, n, temp_mat, n, 0._dp, a_pinverse, n)
1078 DEALLOCATE (eig, work, dinv, temp_mat)
1080 CALL timestop(handle)
1095 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: a, b
1096 REAL(kind=
dp),
DIMENSION(3) :: a_mirror
1098 REAL(kind=
dp) :: length_of_b, scapro
1099 REAL(kind=
dp),
DIMENSION(3) :: d
1101 length_of_b = sqrt(b(1)*b(1) + b(2)*b(2) + b(3)*b(3))
1103 IF (length_of_b > eps_geo)
THEN
1105 d(:) = b(:)/length_of_b
1108 scapro = a(1)*d(1) + a(2)*d(2) + a(3)*d(3)
1110 a_mirror(:) = a(:) - 2.0_dp*scapro*d(:)
1114 a_mirror(:) = 0.0_dp
1133 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: a
1134 REAL(kind=
dp),
INTENT(IN) :: phi
1135 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: b
1136 REAL(kind=
dp),
DIMENSION(3) :: a_rot
1138 REAL(kind=
dp) :: length_of_b
1139 REAL(kind=
dp),
DIMENSION(3, 3) :: rotmat
1141 length_of_b = sqrt(b(1)*b(1) + b(2)*b(2) + b(3)*b(3))
1142 IF (length_of_b > eps_geo)
THEN
1148 a_rot(:) = matmul(rotmat, a)
1166 PURE SUBROUTINE set_diag_scalar_d(a, b)
1167 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: a
1168 REAL(kind=
dp),
INTENT(IN) :: b
1172 n = min(
SIZE(a, 1),
SIZE(a, 2))
1177 END SUBROUTINE set_diag_scalar_d
1184 PURE SUBROUTINE set_diag_scalar_z(a, b)
1185 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(INOUT) :: a
1186 COMPLEX(KIND=dp),
INTENT(IN) :: b
1190 n = min(
SIZE(a, 1),
SIZE(a, 2))
1195 END SUBROUTINE set_diag_scalar_z
1206 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: a
1207 CHARACTER(LEN=*),
INTENT(IN) :: option
1211 n = min(
SIZE(a, 1),
SIZE(a, 2))
1213 IF (option ==
"lower_to_upper")
THEN
1215 a(i, i + 1:n) = a(i + 1:n, i)
1217 ELSE IF (option ==
"upper_to_lower")
THEN
1219 a(i + 1:n, i) = a(i, i + 1:n)
1221 ELSE IF (option ==
"anti_lower_to_upper")
THEN
1223 a(i, i + 1:n) = -a(i + 1:n, i)
1225 ELSE IF (option ==
"anti_upper_to_lower")
THEN
1227 a(i + 1:n, i) = -a(i, i + 1:n)
1230 cpabort(
"Invalid option <"//trim(option)//
"> was specified for parameter #2")
1242 PURE SUBROUTINE unit_matrix_d(a)
1243 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: a
1248 END SUBROUTINE unit_matrix_d
1254 PURE SUBROUTINE unit_matrix_z(a)
1255 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(INOUT) :: a
1257 a(:, :) = (0.0_dp, 0.0_dp)
1260 END SUBROUTINE unit_matrix_z
1272 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: a, b
1273 REAL(kind=
dp),
DIMENSION(3) :: c
1275 c(1) = a(2)*b(3) - a(3)*b(2)
1276 c(2) = a(3)*b(1) - a(1)*b(3)
1277 c(3) = a(1)*b(2) - a(2)*b(1)
1289 INTEGER,
INTENT(IN) :: a, b
1292 INTEGER :: aa, ab, l, rem, s
1324 INTEGER,
INTENT(IN) :: a, b
1334 lcm = abs((a/tmp)*b)
1348 INTEGER,
PARAMETER :: maxit = 100
1349 REAL(
dp),
PARAMETER :: eps = epsilon(0.0_dp), &
1350 fpmin = tiny(0.0_dp)
1353 REAL(
dp) :: fact, prev, sum1, term
1355 IF (x <= 0._dp)
THEN
1356 cpabort(
"Invalid argument")
1361 ELSE IF (x <= -log(eps))
THEN
1365 fact = fact*x/real(k,
dp)
1366 term = fact/real(k,
dp)
1368 IF (term < eps*sum1)
EXIT
1370 ei = sum1 + log(x) +
euler
1376 term = term*real(k,
dp)/x
1377 IF (term < eps)
EXIT
1378 IF (term < prev)
THEN
1385 ei = exp(x)*(1._dp + sum1)/x
1402 REAL(
dp),
INTENT(IN) :: xx
1405 REAL(
dp),
PARAMETER :: dx0 = 1.461632144968362341262659542325721325e0_dp, p1(7) = [ &
1406 .895385022981970e-02_dp, .477762828042627e+01_dp, .142441585084029e+03_dp, &
1407 .118645200713425e+04_dp, .363351846806499e+04_dp, .413810161269013e+04_dp, &
1408 .130560269827897e+04_dp], p2(4) = [-.212940445131011e+01_dp, -.701677227766759e+01_dp, &
1409 -.448616543918019e+01_dp, -.648157123766197e+00_dp], piov4 = .785398163397448e0_dp, q1(6) &
1410 = [.448452573429826e+02_dp, .520752771467162e+03_dp, .221000799247830e+04_dp, &
1411 .364127349079381e+04_dp, .190831076596300e+04_dp, .691091682714533e-05_dp]
1412 REAL(
dp),
PARAMETER :: q2(4) = [.322703493791143e+02_dp, .892920700481861e+02_dp, &
1413 .546117738103215e+02_dp, .777788548522962e+01_dp]
1415 INTEGER :: i, m, n, nq
1416 REAL(
dp) :: aug, den, sgn, upper, w, x, xmax1, xmx0, &
1426 xmax1 = min(real(huge(0), kind=
dp), 1.0e0_dp/epsilon(1.0e0_dp))
1431 IF (x < 0.5e0_dp)
THEN
1433 IF (abs(x) <= xsmall)
THEN
1434 IF (x == 0.0e0_dp)
THEN
1446 IF (w <= 0.0e0_dp)
THEN
1450 IF (w >= xmax1)
THEN
1457 nq = int(w*4.0e0_dp)
1458 w = 4.0e0_dp*(w - nq*.25e0_dp)
1461 IF ((n + n) /= nq) w = 1.0e0_dp - w
1464 IF ((m + m) /= n) sgn = -sgn
1471 aug = sgn*((sin(z)/cos(z))*4.0e0_dp)
1473 IF (z == 0.0e0_dp)
THEN
1478 aug = sgn*((cos(z)/sin(z))*4.0e0_dp)
1484 IF (x <= 3.0e0_dp)
THEN
1490 den = (den + q1(i))*x
1491 upper = (upper + p1(i + 1))*x
1494 den = (upper + p1(7))/(den + q1(6))
1496 fn_val = den*xmx0 + aug
1507 den = (den + q2(i))*w
1508 upper = (upper + p2(i + 1))*w
1511 aug = upper/(den + q2(4)) - 0.5e0_dp/x + aug
1514 fn_val = aug + log(x)
1530 INTEGER,
INTENT(IN) :: n
1531 REAL(
dp),
INTENT(IN) :: x
1534 INTEGER,
PARAMETER :: maxit = 100
1535 REAL(
dp),
PARAMETER :: eps = 6.e-14_dp,
euler = 0.5772156649015328606065120_dp, &
1536 fpmin = tiny(0.0_dp)
1538 INTEGER :: i, ii, nm1
1539 REAL(
dp) :: a, b, c, d, del, fact, h, psi
1543 IF (n < 0 .OR. x < 0.0_dp .OR. (x == 0.0_dp .AND. (n == 0 .OR. n == 1)))
THEN
1544 cpabort(
"Invalid argument")
1545 ELSE IF (n == 0)
THEN
1547 ELSE IF (x == 0.0_dp)
THEN
1549 ELSE IF (x > 1.0_dp)
THEN
1557 d = 1.0_dp/(a*d + b)
1561 IF (abs(del - 1.0_dp) < eps)
THEN
1566 cpabort(
"continued fraction failed in expint")
1577 del = -fact/(i - nm1)
1581 psi = psi + 1.0_dp/ii
1583 del = fact*(-log(x) + psi)
1586 IF (abs(del) < abs(
expint)*eps)
RETURN
1588 cpabort(
"series failed in expint")
1605 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: a
1606 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: d
1607 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: v
1614 CALL diag(n, a, d, v)
1617 CALL eigsrt(n, d, v)
1633 INTEGER,
INTENT(IN) :: n
1634 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: a
1635 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: d
1636 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: v
1638 CHARACTER(len=*),
PARAMETER :: routinen =
'diag'
1639 REAL(kind=
dp),
PARAMETER :: a_eps = 1.0e-10_dp, d_eps = 1.0e-3_dp
1641 INTEGER :: handle, i, ip, iq
1642 REAL(kind=
dp) :: a_max, apq, c, d_min, dip, diq, g, h, s, &
1643 t, tau, theta, tresh
1644 REAL(kind=
dp),
DIMENSION(n) :: b, z
1646 CALL timeset(routinen, handle)
1650 a_max = max(a_max, maxval(abs(a(ip, ip + 1:n))))
1660 d_min = max(d_eps, minval(abs(b)))
1661 IF (a_max < a_eps*d_min)
THEN
1662 CALL timestop(handle)
1665 tresh = merge(a_max, 0.0_dp, (i < 4))
1672 g = 100.0_dp*abs(apq)
1673 IF (tresh < abs(apq))
THEN
1675 IF ((abs(h) + g) /= abs(h))
THEN
1676 theta = 0.5_dp*h/apq
1677 t = 1.0_dp/(abs(theta) + sqrt(1.0_dp + theta**2))
1678 IF (theta < 0.0_dp) t = -t
1682 c = 1.0_dp/sqrt(1.0_dp + t**2)
1684 tau = s/(1.0_dp + c)
1691 CALL jrotate(a(1:ip - 1, ip), a(1:ip - 1, iq), s, tau)
1692 CALL jrotate(a(ip, ip + 1:iq - 1), a(ip + 1:iq - 1, iq), s, tau)
1693 CALL jrotate(a(ip, iq + 1:n), a(iq, iq + 1:n), s, tau)
1694 CALL jrotate(v(:, ip), v(:, iq), s, tau)
1695 ELSE IF ((4 < i) .AND. &
1696 ((abs(dip) + g) == abs(dip)) .AND. &
1697 ((abs(diq) + g) == abs(diq)))
THEN
1705 a_max = max(a_max, maxval(abs(a(ip, ip + 1:n))))
1708 WRITE (*,
'(/,T2,A,/)')
'Too many iterations in jacobi'
1710 CALL timestop(handle)
1724 PURE SUBROUTINE jrotate(a, b, ss, tt)
1725 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: a, b
1726 REAL(kind=
dp),
INTENT(IN) :: ss, tt
1728 REAL(kind=
dp) :: u, v
1734 b = b*(u + ss*v) + a*v
1736 END SUBROUTINE jrotate
1748 SUBROUTINE eigsrt(n, d, v)
1749 INTEGER,
INTENT(IN) :: n
1750 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: d
1751 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: v
1756 j = sum(minloc(d(i:n))) + i - 1
1758 CALL swap(d(i), d(j))
1759 CALL swap(v(:, i), v(:, j))
1763 END SUBROUTINE eigsrt
1773 ELEMENTAL SUBROUTINE swap_scalar(a, b)
1774 REAL(kind=
dp),
INTENT(INOUT) :: a, b
1782 END SUBROUTINE swap_scalar
1792 SUBROUTINE swap_vector(a, b)
1793 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: a, b
1800 IF (n /=
SIZE(b))
THEN
1801 cpabort(
"Check the array bounds of the parameters")
1810 END SUBROUTINE swap_vector
1823 REAL(
dp),
INTENT(in) :: eps, omg
1824 REAL(
dp),
INTENT(out) :: r_cutoff
1826 CHARACTER(LEN=*),
PARAMETER :: routinen =
'erfc_cutoff'
1828 REAL(
dp),
PARAMETER :: abstol = 1e-10_dp, soltol = 1e-16_dp
1829 REAL(
dp) :: r0, f0, fprime0, delta_r
1830 INTEGER :: iter, handle
1831 INTEGER,
PARAMETER :: itermax = 1000
1833 CALL timeset(routinen, handle)
1836 r0 = sqrt(-log(eps*omg*10**2))/omg
1837 CALL eval_transc_func(r0, eps, omg, f0, fprime0)
1839 DO iter = 1, itermax
1840 delta_r = f0/fprime0
1842 CALL eval_transc_func(r0, eps, omg, f0, fprime0)
1843 IF (abs(delta_r) < abstol .OR. abs(f0) < soltol)
EXIT
1845 cpassert(iter <= itermax)
1848 CALL timestop(handle)
1858 ELEMENTAL SUBROUTINE eval_transc_func(r, eps, omega, fn, df)
1859 REAL(
dp),
INTENT(in) :: r, eps, omega
1860 REAL(
dp),
INTENT(out) :: fn, df
1865 fn = erfc(qr) - r*eps
1866 df = -2.0_dp*
oorootpi*omega*exp(-qr**2) - eps
1867 END SUBROUTINE eval_transc_func
1878 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(IN) :: matrix
1879 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(OUT) :: eigenvectors
1880 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: eigenvalues
1882 CHARACTER(len=*),
PARAMETER :: routinen =
'diag_complex'
1884 COMPLEX(KIND=dp),
DIMENSION(:),
ALLOCATABLE :: work
1885 INTEGER :: handle, info, liwork, lrwork, lwork, n
1886 INTEGER,
DIMENSION(:),
ALLOCATABLE :: iwork
1887 REAL(kind=
dp),
DIMENSION(:),
ALLOCATABLE :: rwork
1889 CALL timeset(routinen, handle)
1891 IF (
SIZE(matrix, 1) /=
SIZE(matrix, 2)) cpabort(
"Expected square matrix")
1895 ALLOCATE (iwork(1), rwork(1), work(1))
1902 CALL zheevd(
'V',
'U', n, eigenvectors, n, eigenvalues, work, lwork, rwork, lrwork, iwork, liwork, info)
1904 lwork = ceiling(real(work(1), kind=
dp))
1905 lrwork = ceiling(rwork(1))
1908 DEALLOCATE (iwork, rwork, work)
1909 ALLOCATE (iwork(liwork), rwork(lrwork), work(lwork))
1910 eigenvectors(:, :) = matrix(:, :)
1913 CALL zheevd(
'V',
'U', n, eigenvectors, n, eigenvalues, work, lwork, rwork, lrwork, iwork, liwork, info)
1915 DEALLOCATE (iwork, rwork, work)
1917 IF (info /= 0) cpabort(
"Diagonalisation of a complex matrix failed")
1919 CALL timestop(handle)
1930 REAL(
dp),
DIMENSION(:, :) :: matrix
1931 COMPLEX(dp),
DIMENSION(:, :) :: evecs
1932 COMPLEX(dp),
DIMENSION(:) :: evals
1934 COMPLEX(dp),
ALLOCATABLE,
DIMENSION(:, :) :: matrix_c
1936 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues
1938 IF (
SIZE(matrix, 1) /=
SIZE(matrix, 2)) cpabort(
"Expected square matrix")
1942 ALLOCATE (matrix_c(n, n), eigenvalues(n))
1944 matrix_c(:, :) = cmplx(0.0_dp, -matrix, kind=
dp)
1946 evals = cmplx(0.0_dp, eigenvalues, kind=
dp)
1948 DEALLOCATE (matrix_c, eigenvalues)
1960 SUBROUTINE zgemm_square_2(A_in, A_trans, B_in, B_trans, C_out)
1961 COMPLEX(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: A_in
1962 CHARACTER,
INTENT(IN) :: A_trans
1963 COMPLEX(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: B_in
1964 CHARACTER,
INTENT(IN) :: B_trans
1965 COMPLEX(kind=dp),
DIMENSION(:, :),
INTENT(INOUT) :: C_out
1967 CHARACTER(len=*),
PARAMETER :: routineN =
'zgemm_square_2'
1969 INTEGER :: handle, n
1972 IF (n /=
SIZE(a_in, 2)) cpabort(
"Non-square array 1 (A).")
1973 IF (n /=
SIZE(b_in, 1)) cpabort(
"Incompatible (rows) array 2 (B).")
1974 IF (n /=
SIZE(b_in, 2)) cpabort(
"Non-square array 2 (B).")
1975 IF (n /=
SIZE(c_out, 1)) cpabort(
"Incompatible (rows) result array 3 (C).")
1976 IF (n /=
SIZE(c_out, 2)) cpabort(
"Incompatible (cols) result array 3 (C).")
1977 IF (.NOT. (a_trans ==
'N' .OR. a_trans ==
'n' .OR. &
1978 a_trans ==
'T' .OR. a_trans ==
't' .OR. &
1979 a_trans ==
'C' .OR. a_trans ==
'c'))
THEN
1980 cpabort(
"Unknown transpose character for array 1 (A).")
1982 IF (.NOT. (b_trans ==
'N' .OR. b_trans ==
'n' .OR. &
1983 b_trans ==
'T' .OR. b_trans ==
't' .OR. &
1984 b_trans ==
'C' .OR. b_trans ==
'c'))
THEN
1985 cpabort(
"Unknown transpose character for array 2 (B).")
1988 CALL timeset(routinen, handle)
1990 CALL zgemm(a_trans, b_trans, n, n, n,
z_one, a_in, n, b_in, n,
z_zero, c_out, n)
1992 CALL timestop(handle)
1994 END SUBROUTINE zgemm_square_2
2005 SUBROUTINE dgemm_square_2(A_in, A_trans, B_in, B_trans, C_out)
2006 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a_in
2007 CHARACTER,
INTENT(IN) :: A_trans
2008 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: b_in
2009 CHARACTER,
INTENT(IN) :: B_trans
2010 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: c_out
2012 CHARACTER(len=*),
PARAMETER :: routineN =
'dgemm_square_2'
2014 INTEGER :: handle, n
2017 IF (n /=
SIZE(a_in, 2)) cpabort(
"Non-square array 1 (A).")
2018 IF (n /=
SIZE(b_in, 1)) cpabort(
"Incompatible (rows) array 2 (B).")
2019 IF (n /=
SIZE(b_in, 2)) cpabort(
"Non-square array 2 (B).")
2020 IF (n /=
SIZE(c_out, 1)) cpabort(
"Incompatible (rows) result array 3 (C).")
2021 IF (n /=
SIZE(c_out, 2)) cpabort(
"Incompatible (cols) result array 3 (C).")
2022 IF (.NOT. (a_trans ==
'N' .OR. a_trans ==
'n' .OR. &
2023 a_trans ==
'T' .OR. a_trans ==
't' .OR. &
2024 a_trans ==
'C' .OR. a_trans ==
'c'))
THEN
2025 cpabort(
"Unknown transpose character for array 1 (A).")
2027 IF (.NOT. (b_trans ==
'N' .OR. b_trans ==
'n' .OR. &
2028 b_trans ==
'T' .OR. b_trans ==
't' .OR. &
2029 b_trans ==
'C' .OR. b_trans ==
'c'))
THEN
2030 cpabort(
"Unknown transpose character for array 2 (B).")
2033 CALL timeset(routinen, handle)
2035 CALL dgemm(a_trans, b_trans, n, n, n, 1.0_dp, a_in, n, b_in, n, 0.0_dp, c_out, n)
2037 CALL timestop(handle)
2039 END SUBROUTINE dgemm_square_2
2052 SUBROUTINE zgemm_square_3(A_in, A_trans, B_in, B_trans, C_in, C_trans, D_out)
2053 COMPLEX(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: A_in
2054 CHARACTER,
INTENT(IN) :: A_trans
2055 COMPLEX(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: B_in
2056 CHARACTER,
INTENT(IN) :: B_trans
2057 COMPLEX(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: C_in
2058 CHARACTER,
INTENT(IN) :: C_trans
2059 COMPLEX(kind=dp),
DIMENSION(:, :),
INTENT(INOUT) :: D_out
2061 CHARACTER(len=*),
PARAMETER :: routineN =
'zgemm_square_3'
2063 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:, :) :: work
2064 INTEGER :: handle, n
2067 IF (n /=
SIZE(a_in, 2)) cpabort(
"Non-square array 1 (A).")
2068 IF (n /=
SIZE(b_in, 1)) cpabort(
"Incompatible (rows) array 2 (B).")
2069 IF (n /=
SIZE(b_in, 2)) cpabort(
"Non-square array 2 (B).")
2070 IF (n /=
SIZE(c_in, 1)) cpabort(
"Incompatible (rows) array 3 (C).")
2071 IF (n /=
SIZE(c_in, 2)) cpabort(
"Non-square array 3 (C).")
2072 IF (n /=
SIZE(d_out, 1)) cpabort(
"Incompatible (rows) result array 4 (D).")
2073 IF (n /=
SIZE(d_out, 2)) cpabort(
"Incompatible (cols) result array 4 (D).")
2074 IF (.NOT. (a_trans ==
'N' .OR. a_trans ==
'n' .OR. &
2075 a_trans ==
'T' .OR. a_trans ==
't' .OR. &
2076 a_trans ==
'C' .OR. a_trans ==
'c'))
THEN
2077 cpabort(
"Unknown transpose character for array 1 (A).")
2079 IF (.NOT. (b_trans ==
'N' .OR. b_trans ==
'n' .OR. &
2080 b_trans ==
'T' .OR. b_trans ==
't' .OR. &
2081 b_trans ==
'C' .OR. b_trans ==
'c'))
THEN
2082 cpabort(
"Unknown transpose character for array 2 (B).")
2084 IF (.NOT. (c_trans ==
'N' .OR. c_trans ==
'n' .OR. &
2085 c_trans ==
'T' .OR. c_trans ==
't' .OR. &
2086 c_trans ==
'C' .OR. c_trans ==
'c'))
THEN
2087 cpabort(
"Unknown transpose character for array 3 (C).")
2090 CALL timeset(routinen, handle)
2092 ALLOCATE (work(n, n), source=
z_zero)
2094 CALL zgemm(a_trans, b_trans, n, n, n,
z_one, a_in, n, b_in, n,
z_zero, work, n)
2095 CALL zgemm(
'N', c_trans, n, n, n,
z_one, work, n, c_in, n,
z_zero, d_out, n)
2099 CALL timestop(handle)
2101 END SUBROUTINE zgemm_square_3
2114 SUBROUTINE dgemm_square_3(A_in, A_trans, B_in, B_trans, C_in, C_trans, D_out)
2115 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a_in
2116 CHARACTER,
INTENT(IN) :: A_trans
2117 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: b_in
2118 CHARACTER,
INTENT(IN) :: B_trans
2119 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: c_in
2120 CHARACTER,
INTENT(IN) :: C_trans
2121 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: d_out
2123 CHARACTER(len=*),
PARAMETER :: routineN =
'dgemm_square_3'
2125 INTEGER :: handle, n
2126 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: work
2129 IF (n /=
SIZE(a_in, 2)) cpabort(
"Non-square array 1 (A).")
2130 IF (n /=
SIZE(b_in, 1)) cpabort(
"Incompatible (rows) array 2 (B).")
2131 IF (n /=
SIZE(b_in, 2)) cpabort(
"Non-square array 2 (B).")
2132 IF (n /=
SIZE(c_in, 1)) cpabort(
"Incompatible (rows) array 3 (C).")
2133 IF (n /=
SIZE(c_in, 2)) cpabort(
"Non-square array 3 (C).")
2134 IF (n /=
SIZE(d_out, 1)) cpabort(
"Incompatible (rows) result array 4 (D).")
2135 IF (n /=
SIZE(d_out, 2)) cpabort(
"Incompatible (cols) result array 4 (D).")
2136 IF (.NOT. (a_trans ==
'N' .OR. a_trans ==
'n' .OR. &
2137 a_trans ==
'T' .OR. a_trans ==
't' .OR. &
2138 a_trans ==
'C' .OR. a_trans ==
'c'))
THEN
2139 cpabort(
"Unknown transpose character for array 1 (A).")
2141 IF (.NOT. (b_trans ==
'N' .OR. b_trans ==
'n' .OR. &
2142 b_trans ==
'T' .OR. b_trans ==
't' .OR. &
2143 b_trans ==
'C' .OR. b_trans ==
'c'))
THEN
2144 cpabort(
"Unknown transpose character for array 2 (B).")
2146 IF (.NOT. (c_trans ==
'N' .OR. c_trans ==
'n' .OR. &
2147 c_trans ==
'T' .OR. c_trans ==
't' .OR. &
2148 c_trans ==
'C' .OR. c_trans ==
'c'))
THEN
2149 cpabort(
"Unknown transpose character for array 3 (C).")
2152 CALL timeset(routinen, handle)
2154 ALLOCATE (work(n, n), source=0.0_dp)
2156 CALL dgemm(a_trans, b_trans, n, n, n, 1.0_dp, a_in, n, b_in, n, 0.0_dp, work, n)
2157 CALL dgemm(
'N', c_trans, n, n, n, 1.0_dp, work, n, c_in, n, 0.0_dp, d_out, n)
2161 CALL timestop(handle)
2163 END SUBROUTINE dgemm_square_3
2174 COMPLEX(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: a_in, b_in
2175 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: eigenvalues
2176 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(OUT) :: eigenvectors
2178 CHARACTER(len=*),
PARAMETER :: routinen =
'geeig_right'
2179 COMPLEX(KIND=dp),
PARAMETER :: cone = cmplx(1.0_dp, 0.0_dp, kind=
dp), &
2180 czero = cmplx(0.0_dp, 0.0_dp, kind=
dp)
2182 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:) :: cevals
2183 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:, :) :: a, b, work
2184 INTEGER :: handle, i, icol, irow, lda, ldb, ldc, &
2185 nao, nc, ncol, nmo, nx
2186 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: evals
2188 CALL timeset(routinen, handle)
2192 nmo =
SIZE(eigenvalues)
2193 ALLOCATE (evals(nao), cevals(nao))
2194 ALLOCATE (work(nao, nao), b(nao, nao), a(nao, nao))
2195 a(:, :) = a_in(:, :)
2196 b(:, :) = b_in(:, :)
2201 evals(:) = -evals(:)
2204 IF (evals(i) < -1.0_dp)
THEN
2215 CALL zcopy(ncol*nao, work(1, nc + 1), 1, eigenvectors(1, nc + 1), 1)
2218 DO icol = nc + 1, nao
2220 work(irow, icol) = czero
2224 evals(nc + 1:nao) = 1.0_dp
2227 cevals(:) = cmplx(1.0_dp/sqrt(evals(:)), 0.0_dp, kind=
dp)
2228 DO i = 1, min(
SIZE(work, 2),
SIZE(cevals))
2229 CALL zscal(min(
SIZE(work, 2),
SIZE(cevals)), cevals(i), work(1, i), 1)
2236 DO icol = nc + 1, nao
2237 a(icol, icol) = 10000*cone
2242 eigenvalues(1:nmo) = evals(1:nmo)
2247 ldc =
SIZE(eigenvectors, 1)
2248 CALL zgemm(
"N",
"N", nao, nx, nc, cone, work, &
2249 lda, b, ldb, czero, eigenvectors, ldc)
2251 DEALLOCATE (evals, cevals, work, b, a)
2253 CALL timestop(handle)
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Definition of mathematical constants and functions.
real(kind=dp), parameter, public oorootpi
complex(kind=dp), parameter, public z_one
real(kind=dp), parameter, public euler
real(kind=dp), dimension(0:maxfac), parameter, public fac
complex(kind=dp), parameter, public z_zero
Collection of simple mathematical functions and subroutines.
subroutine, public get_pseudo_inverse_svd(a, a_pinverse, rskip, determinant, sval)
returns the pseudoinverse of a real, square matrix using singular value decomposition
subroutine, public jacobi(a, d, v)
Jacobi matrix diagonalization. The eigenvalues are returned in vector d and the eigenvectors are retu...
elemental real(kind=dp) function, public binomial(n, k)
The binomial coefficient n over k for 0 <= k <= n is calculated, otherwise zero is returned.
elemental integer function, public lcm(a, b)
computes the least common multiplier of two numbers
subroutine, public get_pseudo_inverse_diag(a, a_pinverse, rskip)
returns the pseudoinverse of a real, symmetric and positive definite matrix using diagonalization.
elemental real(kind=dp) function, public binomial_gen(z, k)
The generalized binomial coefficient z over k for 0 <= k <= n is calculated. (z) z*(z-1)*....
subroutine, public invmat_symm(a, potrf, uplo)
returns inverse of real symmetric, positive definite matrix
pure real(kind=dp) function, dimension(min(size(a, 1), size(a, 2))), public get_diag(a)
Return the diagonal elements of matrix a as a vector.
pure real(kind=dp) function, dimension(3), public reflect_vector(a, b)
Reflection of the vector a through a mirror plane defined by the normal vector b. The reflected vecto...
pure real(kind=dp) function, public angle(a, b)
Calculation of the angle between the vectors a and b. The angle is returned in radians.
subroutine, public diag_complex(matrix, eigenvectors, eigenvalues)
Diagonalizes a local complex Hermitian matrix using LAPACK. Based on cp_cfm_heevd.
subroutine, public diag_antisym(matrix, evecs, evals)
Helper routine for diagonalizing anti symmetric matrices.
pure subroutine, public build_rotmat(phi, a, rotmat)
The rotation matrix rotmat which rotates a vector about a rotation axis defined by the vector a is bu...
pure real(dp) function, public digamma(xx)
Computes the digamma function, the logarithmic derivative of the gamma function.
elemental integer function, public gcd(a, b)
computes the greatest common divisor of two number
subroutine, public symmetrize_matrix(a, option)
Symmetrize the matrix a.
pure real(kind=dp) function, dimension(3, 3), public inv_3x3(a)
Returns the inverse of the 3 x 3 matrix a.
subroutine, public invmat(a, info)
returns inverse of matrix using the lapack routines DGETRF and DGETRI
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
subroutine, public diag(n, a, d, v)
Diagonalize matrix a. The eigenvalues are returned in vector d and the eigenvectors are returned in m...
subroutine, public geeig_right(a_in, b_in, eigenvalues, eigenvectors)
Solve the generalized eigenvalue equation for complex matrices A*v = B*v*λ
pure real(kind=dp) function, dimension(3), public rotate_vector(a, phi, b)
Rotation of the vector a about an rotation axis defined by the vector b. The rotation angle is phi (r...
subroutine, public erfc_cutoff(eps, omg, r_cutoff)
compute a truncation radius for the shortrange operator
logical function, public abnormal_value(a)
determines if a value is not normal (e.g. for Inf and Nan) based on IO to work also under optimizatio...
elemental impure real(dp) function, public expint(n, x)
computes the exponential integral En(x) = Int(exp(-x*t)/t^n,t=1..infinity) x>0, n=0,...
pure real(kind=dp) function, public dihedral_angle(ab, bc, cd)
Returns the dihedral angle, i.e. the angle between the planes defined by the vectors (-ab,...
real(kind=dp) function, public pswitch(x, a, b, order)
Polynomial (5th degree) switching function f(a) = 1 .... f(b) = 0 with f'(a) = f"(a) = f'(b) = f"(b) ...
pure real(kind=dp) function, dimension(3), public vector_product(a, b)
Calculation of the vector product c = a x b.
pure real(kind=dp) function, public multinomial(n, k)
Calculates the multinomial coefficients.