31#include "../base/base_uses.f90"
36 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
37 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cp_cfm_basic_linalg'
59 REAL(kind=
dp),
EXTERNAL :: zlange, pzlange
62 MODULE PROCEDURE cp_cfm_dscale, cp_cfm_zscale
78 COMPLEX(KIND=dp),
INTENT(OUT) :: det_a
79 COMPLEX(KIND=dp) :: determinant
81 COMPLEX(KIND=dp),
DIMENSION(:, :),
POINTER :: a
82 INTEGER :: n, i, info, p
83 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
84 COMPLEX(KIND=dp),
DIMENSION(:),
POINTER :: diag
86#if defined(__SCALAPACK)
87 INTEGER,
EXTERNAL :: indxl2g
88 INTEGER :: myprow, nprow, npcol, nrow_local, nrow_block, irow_local, &
89 mypcol, ncol_local, ncol_block, icol_local, j
90 INTEGER,
DIMENSION(9) :: desca
94 matrix_struct=matrix_a%matrix_struct, &
98 a => matrix_lu%local_data
99 n = matrix_lu%matrix_struct%nrow_global
105#if defined(__SCALAPACK)
107 desca(:) = matrix_lu%matrix_struct%descriptor(:)
108 CALL pzgetrf(n, n, a(1, 1), 1, 1, desca, ipivot, info)
109 myprow = matrix_lu%matrix_struct%context%mepos(1)
110 mypcol = matrix_lu%matrix_struct%context%mepos(2)
111 nprow = matrix_lu%matrix_struct%context%num_pe(1)
112 npcol = matrix_lu%matrix_struct%context%num_pe(2)
113 nrow_local = matrix_lu%matrix_struct%nrow_locals(myprow)
114 nrow_block = matrix_lu%matrix_struct%nrow_block
115 ncol_block = matrix_lu%matrix_struct%ncol_block
116 ncol_local = matrix_lu%matrix_struct%ncol_locals(mypcol)
118 DO irow_local = 1, nrow_local
119 i = indxl2g(irow_local, nrow_block, myprow, matrix_lu%matrix_struct%first_p_pos(1), nprow)
120 DO icol_local = 1, ncol_local
121 j = indxl2g(icol_local, ncol_block, mypcol, matrix_lu%matrix_struct%first_p_pos(2), npcol)
122 IF (i == j) diag(i) = matrix_lu%local_data(irow_local, icol_local)
125 CALL matrix_lu%matrix_struct%para_env%sum(diag)
126 determinant = product(diag)
127 DO irow_local = 1, nrow_local
128 i = indxl2g(irow_local, nrow_block, myprow, matrix_lu%matrix_struct%first_p_pos(1), nprow)
129 IF (ipivot(irow_local) /= i) p = p + 1
131 CALL matrix_lu%matrix_struct%para_env%sum(p)
135 CALL zgetrf(n, n, a(1, 1), n, ipivot, info)
137 diag(i) = matrix_lu%local_data(i, i)
139 determinant = product(diag)
141 IF (ipivot(i) /= i) p = p + 1
147 det_a = determinant*(-2*mod(p, 2) + 1.0_dp)
158 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_a, matrix_b, matrix_c
160 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_schur_product'
162 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, b, c
163 INTEGER :: handle, icol_local, irow_local, mypcol, &
164 myprow, ncol_local, nrow_local
166 CALL timeset(routinen, handle)
168 myprow = matrix_a%matrix_struct%context%mepos(1)
169 mypcol = matrix_a%matrix_struct%context%mepos(2)
171 a => matrix_a%local_data
172 b => matrix_b%local_data
173 c => matrix_c%local_data
175 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
176 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
178 DO icol_local = 1, ncol_local
179 DO irow_local = 1, nrow_local
180 c(irow_local, icol_local) = a(irow_local, icol_local)*b(irow_local, icol_local)
184 CALL timestop(handle)
194 SUBROUTINE cp_cfm_schur_product_cc(matrix_a, matrix_b, matrix_c)
196 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_a, matrix_b, matrix_c
198 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_schur_product_cc'
200 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, b, c
201 INTEGER :: handle, icol_local, irow_local, mypcol, &
202 myprow, ncol_local, nrow_local
204 CALL timeset(routinen, handle)
206 myprow = matrix_a%matrix_struct%context%mepos(1)
207 mypcol = matrix_a%matrix_struct%context%mepos(2)
209 a => matrix_a%local_data
210 b => matrix_b%local_data
211 c => matrix_c%local_data
213 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
214 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
216 DO icol_local = 1, ncol_local
217 DO irow_local = 1, nrow_local
218 c(irow_local, icol_local) = a(irow_local, icol_local)*conjg(b(irow_local, icol_local))
222 CALL timestop(handle)
224 END SUBROUTINE cp_cfm_schur_product_cc
244 COMPLEX(kind=dp),
INTENT(in) :: alpha
246 COMPLEX(kind=dp),
INTENT(in),
OPTIONAL :: beta
247 TYPE(
cp_cfm_type),
INTENT(IN),
OPTIONAL :: matrix_b
249 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_scale_and_add'
251 COMPLEX(kind=dp) :: my_beta
252 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, b
253 INTEGER :: handle, icol_local, irow_local, mypcol, &
254 myprow, ncol_local, nrow_local
256 CALL timeset(routinen, handle)
259 IF (
PRESENT(beta)) my_beta = beta
263 myprow = matrix_a%matrix_struct%context%mepos(1)
264 mypcol = matrix_a%matrix_struct%context%mepos(2)
266 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
267 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
269 a => matrix_a%local_data
271 IF (my_beta ==
z_zero)
THEN
275 ELSE IF (alpha ==
z_one)
THEN
276 CALL timestop(handle)
279 a(:, :) = alpha*a(:, :)
283 cpassert(
PRESENT(matrix_b))
284 IF (matrix_a%matrix_struct%context /= matrix_b%matrix_struct%context) &
285 cpabort(
"matrixes must be in the same blacs context")
288 matrix_b%matrix_struct))
THEN
290 b => matrix_b%local_data
293 IF (my_beta ==
z_one)
THEN
295 DO icol_local = 1, ncol_local
296 DO irow_local = 1, nrow_local
297 a(irow_local, icol_local) = b(irow_local, icol_local)
302 DO icol_local = 1, ncol_local
303 DO irow_local = 1, nrow_local
304 a(irow_local, icol_local) = my_beta*b(irow_local, icol_local)
308 ELSE IF (alpha ==
z_one)
THEN
309 IF (my_beta ==
z_one)
THEN
311 DO icol_local = 1, ncol_local
312 DO irow_local = 1, nrow_local
313 a(irow_local, icol_local) = a(irow_local, icol_local) + b(irow_local, icol_local)
318 DO icol_local = 1, ncol_local
319 DO irow_local = 1, nrow_local
320 a(irow_local, icol_local) = a(irow_local, icol_local) + my_beta*b(irow_local, icol_local)
326 DO icol_local = 1, ncol_local
327 DO irow_local = 1, nrow_local
328 a(irow_local, icol_local) = alpha*a(irow_local, icol_local) + my_beta*b(irow_local, icol_local)
333#if defined(__SCALAPACK)
334 cpabort(
"to do (pdscal,pdcopy,pdaxpy)")
340 CALL timestop(handle)
355 COMPLEX(kind=dp),
INTENT(in) :: alpha
357 COMPLEX(kind=dp),
INTENT(in) :: beta
360 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_scale_and_add_fm'
362 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
363 INTEGER :: handle, icol_local, irow_local, mypcol, &
364 myprow, ncol_local, nrow_local
365 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: b
367 CALL timeset(routinen, handle)
371 myprow = matrix_a%matrix_struct%context%mepos(1)
372 mypcol = matrix_a%matrix_struct%context%mepos(2)
374 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
375 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
377 a => matrix_a%local_data
383 ELSE IF (alpha ==
z_one)
THEN
384 CALL timestop(handle)
387 a(:, :) = alpha*a(:, :)
391 IF (matrix_a%matrix_struct%context /= matrix_b%matrix_struct%context) &
392 cpabort(
"matrices must be in the same blacs context")
395 matrix_b%matrix_struct))
THEN
397 b => matrix_b%local_data
400 IF (beta ==
z_one)
THEN
402 DO icol_local = 1, ncol_local
403 DO irow_local = 1, nrow_local
404 a(irow_local, icol_local) = b(irow_local, icol_local)
409 DO icol_local = 1, ncol_local
410 DO irow_local = 1, nrow_local
411 a(irow_local, icol_local) = beta*b(irow_local, icol_local)
415 ELSE IF (alpha ==
z_one)
THEN
416 IF (beta ==
z_one)
THEN
418 DO icol_local = 1, ncol_local
419 DO irow_local = 1, nrow_local
420 a(irow_local, icol_local) = a(irow_local, icol_local) + b(irow_local, icol_local)
425 DO icol_local = 1, ncol_local
426 DO irow_local = 1, nrow_local
427 a(irow_local, icol_local) = a(irow_local, icol_local) + beta*b(irow_local, icol_local)
433 DO icol_local = 1, ncol_local
434 DO irow_local = 1, nrow_local
435 a(irow_local, icol_local) = alpha*a(irow_local, icol_local) + beta*b(irow_local, icol_local)
440#if defined(__SCALAPACK)
441 cpabort(
"to do (pdscal,pdcopy,pdaxpy)")
447 CALL timestop(handle)
463 COMPLEX(kind=dp),
INTENT(out) :: determinant
465 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_lu_decompose'
467 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
468 INTEGER :: counter, handle, info, irow, nrow_global
469 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
471#if defined(__SCALAPACK)
472 INTEGER :: icol, ncol_local, nrow_local
473 INTEGER,
DIMENSION(9) :: desca
474 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
479 CALL timeset(routinen, handle)
481 nrow_global = matrix_a%matrix_struct%nrow_global
482 a => matrix_a%local_data
484 ALLOCATE (ipivot(nrow_global))
485#if defined(__SCALAPACK)
486 CALL cp_cfm_get_info(matrix_a, nrow_local=nrow_local, ncol_local=ncol_local, &
487 row_indices=row_indices, col_indices=col_indices)
489 desca(:) = matrix_a%matrix_struct%descriptor(:)
490 CALL pzgetrf(nrow_global, nrow_global, a(1, 1), 1, 1, desca, ipivot, info)
493 DO irow = 1, nrow_local
494 IF (ipivot(irow) .NE. row_indices(irow)) counter = counter + 1
497 IF (mod(counter, 2) == 0)
THEN
506 DO WHILE (irow <= nrow_local .AND. icol <= ncol_local)
507 IF (row_indices(irow) < col_indices(icol))
THEN
509 ELSE IF (row_indices(irow) > col_indices(icol))
THEN
512 determinant = determinant*a(irow, icol)
517 CALL matrix_a%matrix_struct%para_env%prod(determinant)
520 CALL zgetrf(nrow_global, nrow_global, a(1, 1), lda, ipivot, info)
523 DO irow = 1, nrow_global
524 IF (ipivot(irow) .NE. irow) counter = counter + 1
525 determinant = determinant*a(irow, irow)
527 IF (mod(counter, 2) == 1) determinant = -1.0_dp*determinant
534 CALL timestop(handle)
564 SUBROUTINE cp_cfm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, &
565 matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, &
567 CHARACTER(len=1),
INTENT(in) :: transa, transb
568 INTEGER,
INTENT(in) :: m, n, k
569 COMPLEX(kind=dp),
INTENT(in) :: alpha
570 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_a, matrix_b
571 COMPLEX(kind=dp),
INTENT(in) :: beta
573 INTEGER,
INTENT(in),
OPTIONAL :: a_first_col, a_first_row, b_first_col, &
574 b_first_row, c_first_col, c_first_row
576 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_gemm'
578 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, b, c
579 INTEGER :: handle, i_a, i_b, i_c, j_a, j_b, j_c
580#if defined(__SCALAPACK)
581 INTEGER,
DIMENSION(9) :: desca, descb, descc
583 INTEGER :: lda, ldb, ldc
586 CALL timeset(routinen, handle)
587 a => matrix_a%local_data
588 b => matrix_b%local_data
589 c => matrix_c%local_data
591 IF (
PRESENT(a_first_row))
THEN
596 IF (
PRESENT(a_first_col))
THEN
601 IF (
PRESENT(b_first_row))
THEN
606 IF (
PRESENT(b_first_col))
THEN
611 IF (
PRESENT(c_first_row))
THEN
616 IF (
PRESENT(c_first_col))
THEN
622#if defined(__SCALAPACK)
623 desca(:) = matrix_a%matrix_struct%descriptor(:)
624 descb(:) = matrix_b%matrix_struct%descriptor(:)
625 descc(:) = matrix_c%matrix_struct%descriptor(:)
627 CALL pzgemm(transa, transb, m, n, k, alpha, a(1, 1), i_a, j_a, desca, &
628 b(1, 1), i_b, j_b, descb, beta, c(1, 1), i_c, j_c, descc)
634 CALL zgemm(transa, transb, m, n, k, alpha, a(i_a, j_a), &
635 lda, b(i_b, j_b), ldb, beta, c(i_c, j_c), ldc)
637 CALL timestop(handle)
650 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in) :: scaling
652 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_column_scale'
654 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
655 INTEGER :: handle, icol_local, ncol_local, &
657#if defined(__SCALAPACK)
658 INTEGER,
DIMENSION(:),
POINTER :: col_indices
661 CALL timeset(routinen, handle)
663 a => matrix_a%local_data
665#if defined(__SCALAPACK)
666 CALL cp_cfm_get_info(matrix_a, nrow_local=nrow_local, ncol_local=ncol_local, col_indices=col_indices)
667 ncol_local = min(ncol_local,
SIZE(scaling))
669 DO icol_local = 1, ncol_local
670 CALL zscal(nrow_local, scaling(col_indices(icol_local)), a(1, icol_local), 1)
673 nrow_local =
SIZE(a, 1)
674 ncol_local = min(
SIZE(a, 2),
SIZE(scaling))
676 DO icol_local = 1, ncol_local
677 CALL zscal(nrow_local, scaling(icol_local), a(1, icol_local), 1)
681 CALL timestop(handle)
690 SUBROUTINE cp_cfm_dscale(alpha, matrix_a)
691 REAL(kind=
dp),
INTENT(in) :: alpha
694 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_dscale'
696 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
699 CALL timeset(routinen, handle)
703 a => matrix_a%local_data
705 CALL zdscal(
SIZE(a), alpha, a(1, 1), 1)
707 CALL timestop(handle)
708 END SUBROUTINE cp_cfm_dscale
718 SUBROUTINE cp_cfm_zscale(alpha, matrix_a)
719 COMPLEX(kind=dp),
INTENT(in) :: alpha
722 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_cfm_zscale'
724 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
727 CALL timeset(routinen, handle)
731 a => matrix_a%local_data
733 CALL zscal(
SIZE(a), alpha, a(1, 1), 1)
735 CALL timestop(handle)
736 END SUBROUTINE cp_cfm_zscale
748 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_a, general_a
749 COMPLEX(kind=dp),
OPTIONAL :: determinant
751 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_solve'
753 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, a_general
754 INTEGER :: counter, handle, info, irow, nrow_global
755 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
757#if defined(__SCALAPACK)
758 INTEGER :: icol, ncol_local, nrow_local
759 INTEGER,
DIMENSION(9) :: desca, descb
760 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
765 CALL timeset(routinen, handle)
767 a => matrix_a%local_data
768 a_general => general_a%local_data
769 nrow_global = matrix_a%matrix_struct%nrow_global
770 ALLOCATE (ipivot(nrow_global))
772#if defined(__SCALAPACK)
773 desca(:) = matrix_a%matrix_struct%descriptor(:)
774 descb(:) = general_a%matrix_struct%descriptor(:)
775 CALL pzgetrf(nrow_global, nrow_global, a(1, 1), 1, 1, desca, ipivot, info)
776 IF (
PRESENT(determinant))
THEN
777 CALL cp_cfm_get_info(matrix_a, nrow_local=nrow_local, ncol_local=ncol_local, &
778 row_indices=row_indices, col_indices=col_indices)
781 DO irow = 1, nrow_local
782 IF (ipivot(irow) .NE. row_indices(irow)) counter = counter + 1
785 IF (mod(counter, 2) == 0)
THEN
794 DO WHILE (irow <= nrow_local .AND. icol <= ncol_local)
795 IF (row_indices(irow) < col_indices(icol))
THEN
797 ELSE IF (row_indices(irow) > col_indices(icol))
THEN
800 determinant = determinant*a(irow, icol)
805 CALL matrix_a%matrix_struct%para_env%prod(determinant)
808 CALL pzgetrs(
"N", nrow_global, nrow_global, a(1, 1), 1, 1, desca, &
809 ipivot, a_general(1, 1), 1, 1, descb, info)
812 ldb =
SIZE(a_general, 1)
813 CALL zgetrf(nrow_global, nrow_global, a(1, 1), lda, ipivot, info)
814 IF (
PRESENT(determinant))
THEN
817 DO irow = 1, nrow_global
818 IF (ipivot(irow) .NE. irow) counter = counter + 1
819 determinant = determinant*a(irow, irow)
821 IF (mod(counter, 2) == 1) determinant = -1.0_dp*determinant
823 CALL zgetrs(
"N", nrow_global, nrow_global, a(1, 1), lda, ipivot, a_general(1, 1), ldb, info)
829 CALL timestop(handle)
841 INTEGER,
INTENT(out),
OPTIONAL :: info_out
843 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_lu_invert'
845 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: work
846 COMPLEX(kind=dp),
DIMENSION(1) :: work1
847 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: mat
848 INTEGER :: handle, info, lwork, nrows_global
849 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
851#if defined(__SCALAPACK)
853 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iwork
854 INTEGER,
DIMENSION(1) :: iwork1
855 INTEGER,
DIMENSION(9) :: desca
860 CALL timeset(routinen, handle)
862 mat => matrix%local_data
863 nrows_global = matrix%matrix_struct%nrow_global
864 cpassert(nrows_global .EQ. matrix%matrix_struct%ncol_global)
865 ALLOCATE (ipivot(nrows_global))
868#if defined(__SCALAPACK)
869 desca = matrix%matrix_struct%descriptor
870 CALL pzgetrf(nrows_global, nrows_global, &
871 mat(1, 1), 1, 1, desca, ipivot, info)
874 CALL zgetrf(nrows_global, nrows_global, &
875 mat(1, 1), lda, ipivot, info)
878 CALL cp_abort(__location__,
"LU decomposition has failed")
882#if defined(__SCALAPACK)
883 CALL pzgetri(nrows_global, mat(1, 1), 1, 1, desca, &
884 ipivot, work1, -1, iwork1, -1, info)
885 lwork = int(work1(1))
886 liwork = int(iwork1(1))
887 ALLOCATE (work(lwork))
888 ALLOCATE (iwork(liwork))
889 CALL pzgetri(nrows_global, mat(1, 1), 1, 1, desca, &
890 ipivot, work, lwork, iwork, liwork, info)
893 CALL zgetri(nrows_global, mat(1, 1), lda, ipivot, work1, -1, info)
894 lwork = int(work1(1))
895 ALLOCATE (work(lwork))
896 CALL zgetri(nrows_global, mat(1, 1), lda, ipivot, work, lwork, info)
901 IF (
PRESENT(info_out))
THEN
905 CALL cp_abort(__location__,
"LU inversion has failed")
908 CALL timestop(handle)
927 INTEGER,
INTENT(in),
OPTIONAL :: n
928 INTEGER,
INTENT(out),
OPTIONAL :: info_out
930 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_cholesky_decompose'
932 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
933 INTEGER :: handle, info, my_n
934#if defined(__SCALAPACK)
935 INTEGER,
DIMENSION(9) :: desca
940 CALL timeset(routinen, handle)
942 my_n = min(matrix%matrix_struct%nrow_global, &
943 matrix%matrix_struct%ncol_global)
949 a => matrix%local_data
951#if defined(__SCALAPACK)
952 desca(:) = matrix%matrix_struct%descriptor(:)
953 CALL pzpotrf(
'U', my_n, a(1, 1), 1, 1, desca, info)
956 CALL zpotrf(
'U', my_n, a(1, 1), lda, info)
959 IF (
PRESENT(info_out))
THEN
963 CALL cp_abort(__location__, &
964 "Cholesky decompose failed: matrix is not positive definite or ill-conditioned")
967 CALL timestop(handle)
983 INTEGER,
INTENT(in),
OPTIONAL :: n
984 INTEGER,
INTENT(out),
OPTIONAL :: info_out
986 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_cholesky_invert'
987 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: aa
988 INTEGER :: info, handle
990#if defined(__SCALAPACK)
991 INTEGER,
DIMENSION(9) :: desca
994 CALL timeset(routinen, handle)
996 my_n = min(matrix%matrix_struct%nrow_global, &
997 matrix%matrix_struct%ncol_global)
1003 aa => matrix%local_data
1005#if defined(__SCALAPACK)
1006 desca = matrix%matrix_struct%descriptor
1007 CALL pzpotri(
'U', my_n, aa(1, 1), 1, 1, desca, info)
1009 CALL zpotri(
'U', my_n, aa(1, 1),
SIZE(aa, 1), info)
1012 IF (
PRESENT(info_out))
THEN
1016 CALL cp_abort(__location__, &
1017 "Cholesky invert failed: the matrix is not positive definite or ill-conditioned.")
1020 CALL timestop(handle)
1037 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_a, matrix_b
1038 COMPLEX(kind=dp),
INTENT(out) :: trace
1040 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_trace'
1042 INTEGER :: handle, mypcol, myprow, ncol_local, &
1043 npcol, nprow, nrow_local
1047 CALL timeset(routinen, handle)
1049 context => matrix_a%matrix_struct%context
1050 myprow = context%mepos(1)
1051 mypcol = context%mepos(2)
1052 nprow = context%num_pe(1)
1053 npcol = context%num_pe(2)
1055 group = matrix_a%matrix_struct%para_env
1057 nrow_local = min(matrix_a%matrix_struct%nrow_locals(myprow), matrix_b%matrix_struct%nrow_locals(myprow))
1058 ncol_local = min(matrix_a%matrix_struct%ncol_locals(mypcol), matrix_b%matrix_struct%ncol_locals(mypcol))
1062 matrix_b%local_data(1:nrow_local, 1:ncol_local))
1064 CALL group%sum(trace)
1066 CALL timestop(handle)
1105 transa_tr, invert_tr, uplo_tr, unit_diag_tr, n_rows, n_cols, &
1107 TYPE(
cp_cfm_type),
INTENT(IN) :: triangular_matrix, matrix_b
1108 CHARACTER,
INTENT(in),
OPTIONAL :: side, transa_tr
1109 LOGICAL,
INTENT(in),
OPTIONAL :: invert_tr
1110 CHARACTER,
INTENT(in),
OPTIONAL :: uplo_tr
1111 LOGICAL,
INTENT(in),
OPTIONAL :: unit_diag_tr
1112 INTEGER,
INTENT(in),
OPTIONAL :: n_rows, n_cols
1113 COMPLEX(kind=dp),
INTENT(in),
OPTIONAL :: alpha
1115 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_triangular_multiply'
1117 CHARACTER :: side_char, transa, unit_diag, uplo
1118 COMPLEX(kind=dp) :: al
1119 INTEGER :: handle, m, n
1122 CALL timeset(routinen, handle)
1128 al = cmplx(1.0_dp, 0.0_dp,
dp)
1130 IF (
PRESENT(side)) side_char = side
1131 IF (
PRESENT(invert_tr)) invert = invert_tr
1132 IF (
PRESENT(uplo_tr)) uplo = uplo_tr
1133 IF (
PRESENT(unit_diag_tr))
THEN
1134 IF (unit_diag_tr)
THEN
1140 IF (
PRESENT(transa_tr)) transa = transa_tr
1141 IF (
PRESENT(alpha)) al = alpha
1142 IF (
PRESENT(n_rows)) m = n_rows
1143 IF (
PRESENT(n_cols)) n = n_cols
1147#if defined(__SCALAPACK)
1148 CALL pztrsm(side_char, uplo, transa, unit_diag, m, n, al, &
1149 triangular_matrix%local_data(1, 1), 1, 1, &
1150 triangular_matrix%matrix_struct%descriptor, &
1151 matrix_b%local_data(1, 1), 1, 1, &
1152 matrix_b%matrix_struct%descriptor(1))
1154 CALL ztrsm(side_char, uplo, transa, unit_diag, m, n, al, &
1155 triangular_matrix%local_data(1, 1), &
1156 SIZE(triangular_matrix%local_data, 1), &
1157 matrix_b%local_data(1, 1),
SIZE(matrix_b%local_data, 1))
1162#if defined(__SCALAPACK)
1163 CALL pztrmm(side_char, uplo, transa, unit_diag, m, n, al, &
1164 triangular_matrix%local_data(1, 1), 1, 1, &
1165 triangular_matrix%matrix_struct%descriptor, &
1166 matrix_b%local_data(1, 1), 1, 1, &
1167 matrix_b%matrix_struct%descriptor(1))
1169 CALL ztrmm(side_char, uplo, transa, unit_diag, m, n, al, &
1170 triangular_matrix%local_data(1, 1), &
1171 SIZE(triangular_matrix%local_data, 1), &
1172 matrix_b%local_data(1, 1),
SIZE(matrix_b%local_data, 1))
1177 CALL timestop(handle)
1190 CHARACTER,
INTENT(in),
OPTIONAL :: uplo
1191 INTEGER,
INTENT(out),
OPTIONAL :: info_out
1193 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_triangular_invert'
1195 CHARACTER :: unit_diag, my_uplo
1196 INTEGER :: handle, info, ncol_global
1197 COMPLEX(kind=dp),
DIMENSION(:, :), &
1199#if defined(__SCALAPACK)
1200 INTEGER,
DIMENSION(9) :: desca
1203 CALL timeset(routinen, handle)
1207 IF (
PRESENT(uplo)) my_uplo = uplo
1209 ncol_global = matrix_a%matrix_struct%ncol_global
1211 a => matrix_a%local_data
1213#if defined(__SCALAPACK)
1214 desca(:) = matrix_a%matrix_struct%descriptor(:)
1215 CALL pztrtri(my_uplo, unit_diag, ncol_global, a(1, 1), 1, 1, desca, info)
1217 CALL ztrtri(my_uplo, unit_diag, ncol_global, a(1, 1), ncol_global, info)
1220 IF (
PRESENT(info_out))
THEN
1224 CALL cp_abort(__location__, &
1225 "triangular invert failed: matrix is not positive definite or ill-conditioned")
1228 CALL timestop(handle)
1240 CHARACTER,
INTENT(in) :: trans
1243 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_transpose'
1245 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: aa, cc
1246 INTEGER :: handle, ncol_global, nrow_global
1247#if defined(__SCALAPACK)
1248 INTEGER,
DIMENSION(9) :: desca, descc
1253 CALL timeset(routinen, handle)
1255 nrow_global = matrix%matrix_struct%nrow_global
1256 ncol_global = matrix%matrix_struct%ncol_global
1258 cpassert(matrixt%matrix_struct%nrow_global == ncol_global)
1259 cpassert(matrixt%matrix_struct%ncol_global == nrow_global)
1261 aa => matrix%local_data
1262 cc => matrixt%local_data
1264#if defined(__SCALAPACK)
1265 desca = matrix%matrix_struct%descriptor
1266 descc = matrixt%matrix_struct%descriptor
1269 CALL pztranu(nrow_global, ncol_global, &
1270 z_one, aa(1, 1), 1, 1, desca, &
1271 z_zero, cc(1, 1), 1, 1, descc)
1273 CALL pztranc(nrow_global, ncol_global, &
1274 z_one, aa(1, 1), 1, 1, desca, &
1275 z_zero, cc(1, 1), 1, 1, descc)
1277 cpabort(
"trans only accepts 'T' or 'C'")
1282 DO jj = 1, ncol_global
1283 DO ii = 1, nrow_global
1284 cc(ii, jj) = aa(jj, ii)
1288 DO jj = 1, ncol_global
1289 DO ii = 1, nrow_global
1290 cc(ii, jj) = conjg(aa(jj, ii))
1294 cpabort(
"trans only accepts 'T' or 'C'")
1298 CALL timestop(handle)
1313 CHARACTER,
INTENT(IN) :: mode
1314 REAL(kind=
dp) :: res
1316 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_norm'
1318 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: aa
1319 INTEGER :: handle, lwork, ncols, ncols_local, &
1321 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work
1323#if defined(__SCALAPACK)
1324 INTEGER,
DIMENSION(9) :: desca
1329 CALL timeset(routinen, handle)
1332 nrow_global=nrows, &
1333 ncol_global=ncols, &
1334 nrow_local=nrows_local, &
1335 ncol_local=ncols_local)
1336 aa => matrix%local_data
1341 CASE (
'1',
'O',
'o')
1342#if defined(__SCALAPACK)
1348#if defined(__SCALAPACK)
1353 CASE (
'F',
'f',
'E',
'e')
1356 cpabort(
"mode input is not valid")
1359 ALLOCATE (work(lwork))
1361#if defined(__SCALAPACK)
1362 desca = matrix%matrix_struct%descriptor
1363 res = pzlange(mode, nrows, ncols, aa(1, 1), 1, 1, desca, work)
1366 res = zlange(mode, nrows, ncols, aa(1, 1), lda, work)
1370 CALL timestop(handle)
1384 INTEGER,
INTENT(IN) :: irow, jrow
1385 REAL(
dp),
INTENT(IN) :: cs, sn
1387 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_rot_rows'
1388 INTEGER :: handle, nrow, ncol
1389 COMPLEX(KIND=dp) :: sn_cmplx
1391#if defined(__SCALAPACK)
1392 INTEGER :: info, lwork
1393 INTEGER,
DIMENSION(9) :: desc
1394 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: work
1397 CALL timeset(routinen, handle)
1399 sn_cmplx = cmplx(sn, 0.0_dp,
dp)
1401#if defined(__SCALAPACK)
1403 ALLOCATE (work(lwork))
1404 desc(:) = matrix%matrix_struct%descriptor(:)
1406 matrix%local_data(1, 1), irow, 1, desc, ncol, &
1407 matrix%local_data(1, 1), jrow, 1, desc, ncol, &
1408 cs, sn_cmplx, work, lwork, info)
1412 CALL zrot(ncol, matrix%local_data(irow, 1), ncol, matrix%local_data(jrow, 1), ncol, cs, sn_cmplx)
1415 CALL timestop(handle)
1429 INTEGER,
INTENT(IN) :: icol, jcol
1430 REAL(
dp),
INTENT(IN) :: cs, sn
1432 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_rot_cols'
1433 INTEGER :: handle, nrow, ncol
1434 COMPLEX(KIND=dp) :: sn_cmplx
1436#if defined(__SCALAPACK)
1437 INTEGER :: info, lwork
1438 INTEGER,
DIMENSION(9) :: desc
1439 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: work
1442 CALL timeset(routinen, handle)
1444 sn_cmplx = cmplx(sn, 0.0_dp,
dp)
1446#if defined(__SCALAPACK)
1448 ALLOCATE (work(lwork))
1449 desc(:) = matrix%matrix_struct%descriptor(:)
1451 matrix%local_data(1, 1), 1, icol, desc, 1, &
1452 matrix%local_data(1, 1), 1, jcol, desc, 1, &
1453 cs, sn_cmplx, work, lwork, info)
1457 CALL zrot(nrow, matrix%local_data(1, icol), 1, matrix%local_data(1, jcol), 1, cs, sn_cmplx)
1460 CALL timestop(handle)
methods related to the blacs parallel environment
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_scale_and_add(alpha, matrix_a, beta, matrix_b)
Scale and add two BLACS matrices (a = alpha*a + beta*b).
subroutine, public cp_cfm_lu_invert(matrix, info_out)
Inverts a matrix using LU decomposition. The input matrix will be overwritten.
real(kind=dp) function, public cp_cfm_norm(matrix, mode)
Norm of matrix using (p)zlange.
subroutine, public cp_cfm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, c_first_row)
Performs one of the matrix-matrix operations: matrix_c = alpha * op1( matrix_a ) * op2( matrix_b ) + ...
subroutine, public cp_cfm_solve(matrix_a, general_a, determinant)
Solve the system of linear equations A*b=A_general using LU decomposition. Pay attention that both ma...
subroutine, public cp_cfm_transpose(matrix, trans, matrixt)
Transposes a BLACS distributed complex matrix.
subroutine, public cp_cfm_rot_rows(matrix, irow, jrow, cs, sn)
Applies a planar rotation defined by cs and sn to the i'th and j'th rows.
subroutine, public cp_cfm_scale_and_add_fm(alpha, matrix_a, beta, matrix_b)
Scale and add two BLACS matrices (a = alpha*a + beta*b). where b is a real matrix (adapted from cp_cf...
subroutine, public cp_cfm_schur_product(matrix_a, matrix_b, matrix_c)
Computes the element-wise (Schur) product of two matrices: C = A \circ B .
subroutine, public cp_cfm_cholesky_invert(matrix, n, info_out)
Used to replace Cholesky decomposition by the inverse.
subroutine, public cp_cfm_triangular_multiply(triangular_matrix, matrix_b, side, transa_tr, invert_tr, uplo_tr, unit_diag_tr, n_rows, n_cols, alpha)
Multiplies in place by a triangular matrix: matrix_b = alpha op(triangular_matrix) matrix_b or (if si...
subroutine, public cp_cfm_cholesky_decompose(matrix, n, info_out)
Used to replace a symmetric positive definite matrix M with its Cholesky decomposition U: M = U^T * U...
subroutine, public cp_cfm_det(matrix_a, det_a)
Computes the determinant (with a correct sign even in parallel environment!) of a complex square matr...
subroutine, public cp_cfm_column_scale(matrix_a, scaling)
Scales columns of the full matrix by corresponding factors.
subroutine, public cp_cfm_rot_cols(matrix, icol, jcol, cs, sn)
Applies a planar rotation defined by cs and sn to the i'th and j'th columnns.
subroutine, public cp_cfm_triangular_invert(matrix_a, uplo, info_out)
Inverts a triangular matrix.
subroutine, public cp_cfm_lu_decompose(matrix_a, determinant)
Computes LU decomposition of a given matrix.
subroutine, public cp_cfm_trace(matrix_a, matrix_b, trace)
Returns the trace of matrix_a^T matrix_b, i.e sum_{i,j}(matrix_a(i,j)*matrix_b(i,j)) .
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_create(matrix, matrix_struct, name)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
represent the structure of a full matrix
logical function, public cp_fm_struct_equivalent(fmstruct1, fmstruct2)
returns true if the two matrix structures are equivalent, false otherwise.
represent a full matrix distributed on many processors
various routines to log and control the output. The idea is that decisions about where to log should ...
sums arrays of real/complex numbers with much reduced round-off as compared to a naive implementation...
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
Represent a complex full matrix.