31#include "../base/base_uses.f90"
36 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
37 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cp_cfm_basic_linalg'
58 REAL(kind=
dp),
EXTERNAL :: zlange, pzlange
61 MODULE PROCEDURE cp_cfm_dscale, cp_cfm_zscale
77 COMPLEX(KIND=dp),
INTENT(OUT) :: det_a
78 COMPLEX(KIND=dp) :: determinant
80 COMPLEX(KIND=dp),
DIMENSION(:, :),
POINTER :: a
81 INTEGER :: n, i, info, p
82 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
83 COMPLEX(KIND=dp),
DIMENSION(:),
POINTER :: diag
85#if defined(__parallel)
86 INTEGER :: myprow, nprow, npcol, nrow_local, irow_local, &
87 mypcol, ncol_local, icol_local, j
88 INTEGER,
DIMENSION(9) :: desca
92 matrix_struct=matrix_a%matrix_struct, &
96 a => matrix_lu%local_data
97 n = matrix_lu%matrix_struct%nrow_global
103#if defined(__parallel)
105 desca(:) = matrix_lu%matrix_struct%descriptor(:)
106 CALL pzgetrf(n, n, a(1, 1), 1, 1, desca, ipivot, info)
107 myprow = matrix_lu%matrix_struct%context%mepos(1)
108 mypcol = matrix_lu%matrix_struct%context%mepos(2)
109 nprow = matrix_lu%matrix_struct%context%num_pe(1)
110 npcol = matrix_lu%matrix_struct%context%num_pe(2)
111 nrow_local = matrix_lu%matrix_struct%nrow_locals(myprow)
112 ncol_local = matrix_lu%matrix_struct%ncol_locals(mypcol)
114 DO irow_local = 1, nrow_local
115 i = matrix_lu%matrix_struct%row_indices(irow_local)
116 DO icol_local = 1, ncol_local
117 j = matrix_lu%matrix_struct%col_indices(icol_local)
118 IF (i == j) diag(i) = matrix_lu%local_data(irow_local, icol_local)
121 CALL matrix_lu%matrix_struct%para_env%sum(diag)
122 determinant = product(diag)
123 DO irow_local = 1, nrow_local
124 i = matrix_lu%matrix_struct%row_indices(irow_local)
125 IF (ipivot(irow_local) /= i) p = p + 1
127 CALL matrix_lu%matrix_struct%para_env%sum(p)
131 CALL zgetrf(n, n, a(1, 1), n, ipivot, info)
133 diag(i) = matrix_lu%local_data(i, i)
135 determinant = product(diag)
137 IF (ipivot(i) /= i) p = p + 1
143 det_a = determinant*(-2*mod(p, 2) + 1.0_dp)
154 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_a, matrix_b, matrix_c
156 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_schur_product'
158 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, b, c
159 INTEGER :: handle, icol_local, irow_local, mypcol, &
160 myprow, ncol_local, nrow_local
162 CALL timeset(routinen, handle)
164 myprow = matrix_a%matrix_struct%context%mepos(1)
165 mypcol = matrix_a%matrix_struct%context%mepos(2)
167 a => matrix_a%local_data
168 b => matrix_b%local_data
169 c => matrix_c%local_data
171 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
172 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
174 DO icol_local = 1, ncol_local
175 DO irow_local = 1, nrow_local
176 c(irow_local, icol_local) = a(irow_local, icol_local)*b(irow_local, icol_local)
180 CALL timestop(handle)
190 SUBROUTINE cp_cfm_schur_product_cc(matrix_a, matrix_b, matrix_c)
192 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_a, matrix_b, matrix_c
194 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_schur_product_cc'
196 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, b, c
197 INTEGER :: handle, icol_local, irow_local, mypcol, &
198 myprow, ncol_local, nrow_local
200 CALL timeset(routinen, handle)
202 myprow = matrix_a%matrix_struct%context%mepos(1)
203 mypcol = matrix_a%matrix_struct%context%mepos(2)
205 a => matrix_a%local_data
206 b => matrix_b%local_data
207 c => matrix_c%local_data
209 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
210 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
212 DO icol_local = 1, ncol_local
213 DO irow_local = 1, nrow_local
214 c(irow_local, icol_local) = a(irow_local, icol_local)*conjg(b(irow_local, icol_local))
218 CALL timestop(handle)
220 END SUBROUTINE cp_cfm_schur_product_cc
240 COMPLEX(kind=dp),
INTENT(in) :: alpha
242 COMPLEX(kind=dp),
INTENT(in),
OPTIONAL :: beta
243 TYPE(
cp_cfm_type),
INTENT(IN),
OPTIONAL :: matrix_b
245 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_scale_and_add'
247 COMPLEX(kind=dp) :: my_beta
248 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, b
249 INTEGER :: handle, icol_local, irow_local, mypcol, &
250 myprow, ncol_local, nrow_local
252 CALL timeset(routinen, handle)
255 IF (
PRESENT(beta)) my_beta = beta
259 myprow = matrix_a%matrix_struct%context%mepos(1)
260 mypcol = matrix_a%matrix_struct%context%mepos(2)
262 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
263 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
265 a => matrix_a%local_data
267 IF (my_beta ==
z_zero)
THEN
271 ELSE IF (alpha ==
z_one)
THEN
272 CALL timestop(handle)
275 a(:, :) = alpha*a(:, :)
279 cpassert(
PRESENT(matrix_b))
280 IF (matrix_a%matrix_struct%context /= matrix_b%matrix_struct%context) &
281 cpabort(
"matrixes must be in the same blacs context")
284 matrix_b%matrix_struct))
THEN
286 b => matrix_b%local_data
289 IF (my_beta ==
z_one)
THEN
291 DO icol_local = 1, ncol_local
292 DO irow_local = 1, nrow_local
293 a(irow_local, icol_local) = b(irow_local, icol_local)
298 DO icol_local = 1, ncol_local
299 DO irow_local = 1, nrow_local
300 a(irow_local, icol_local) = my_beta*b(irow_local, icol_local)
304 ELSE IF (alpha ==
z_one)
THEN
305 IF (my_beta ==
z_one)
THEN
307 DO icol_local = 1, ncol_local
308 DO irow_local = 1, nrow_local
309 a(irow_local, icol_local) = a(irow_local, icol_local) + b(irow_local, icol_local)
314 DO icol_local = 1, ncol_local
315 DO irow_local = 1, nrow_local
316 a(irow_local, icol_local) = a(irow_local, icol_local) + my_beta*b(irow_local, icol_local)
322 DO icol_local = 1, ncol_local
323 DO irow_local = 1, nrow_local
324 a(irow_local, icol_local) = alpha*a(irow_local, icol_local) + my_beta*b(irow_local, icol_local)
329#if defined(__parallel)
330 cpabort(
"to do (pdscal,pdcopy,pdaxpy)")
336 CALL timestop(handle)
351 COMPLEX(kind=dp),
INTENT(in) :: alpha
353 COMPLEX(kind=dp),
INTENT(in) :: beta
356 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_scale_and_add_fm'
358 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
359 INTEGER :: handle, icol_local, irow_local, mypcol, &
360 myprow, ncol_local, nrow_local
361 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: b
363 CALL timeset(routinen, handle)
367 myprow = matrix_a%matrix_struct%context%mepos(1)
368 mypcol = matrix_a%matrix_struct%context%mepos(2)
370 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
371 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
373 a => matrix_a%local_data
379 ELSE IF (alpha ==
z_one)
THEN
380 CALL timestop(handle)
383 a(:, :) = alpha*a(:, :)
387 IF (matrix_a%matrix_struct%context /= matrix_b%matrix_struct%context) &
388 cpabort(
"matrices must be in the same blacs context")
391 matrix_b%matrix_struct))
THEN
393 b => matrix_b%local_data
396 IF (beta ==
z_one)
THEN
398 DO icol_local = 1, ncol_local
399 DO irow_local = 1, nrow_local
400 a(irow_local, icol_local) = b(irow_local, icol_local)
405 DO icol_local = 1, ncol_local
406 DO irow_local = 1, nrow_local
407 a(irow_local, icol_local) = beta*b(irow_local, icol_local)
411 ELSE IF (alpha ==
z_one)
THEN
412 IF (beta ==
z_one)
THEN
414 DO icol_local = 1, ncol_local
415 DO irow_local = 1, nrow_local
416 a(irow_local, icol_local) = a(irow_local, icol_local) + b(irow_local, icol_local)
421 DO icol_local = 1, ncol_local
422 DO irow_local = 1, nrow_local
423 a(irow_local, icol_local) = a(irow_local, icol_local) + beta*b(irow_local, icol_local)
429 DO icol_local = 1, ncol_local
430 DO irow_local = 1, nrow_local
431 a(irow_local, icol_local) = alpha*a(irow_local, icol_local) + beta*b(irow_local, icol_local)
436#if defined(__parallel)
437 cpabort(
"to do (pdscal,pdcopy,pdaxpy)")
443 CALL timestop(handle)
459 COMPLEX(kind=dp),
INTENT(out) :: determinant
461 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_lu_decompose'
463 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
464 INTEGER :: counter, handle, info, irow, nrow_global
465 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
467#if defined(__parallel)
468 INTEGER :: icol, ncol_local, nrow_local
469 INTEGER,
DIMENSION(9) :: desca
470 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
475 CALL timeset(routinen, handle)
477 nrow_global = matrix_a%matrix_struct%nrow_global
478 a => matrix_a%local_data
480 ALLOCATE (ipivot(nrow_global))
481#if defined(__parallel)
482 CALL cp_cfm_get_info(matrix_a, nrow_local=nrow_local, ncol_local=ncol_local, &
483 row_indices=row_indices, col_indices=col_indices)
485 desca(:) = matrix_a%matrix_struct%descriptor(:)
486 CALL pzgetrf(nrow_global, nrow_global, a(1, 1), 1, 1, desca, ipivot, info)
489 DO irow = 1, nrow_local
490 IF (ipivot(irow) .NE. row_indices(irow)) counter = counter + 1
493 IF (mod(counter, 2) == 0)
THEN
502 DO WHILE (irow <= nrow_local .AND. icol <= ncol_local)
503 IF (row_indices(irow) < col_indices(icol))
THEN
505 ELSE IF (row_indices(irow) > col_indices(icol))
THEN
508 determinant = determinant*a(irow, icol)
513 CALL matrix_a%matrix_struct%para_env%prod(determinant)
516 CALL zgetrf(nrow_global, nrow_global, a(1, 1), lda, ipivot, info)
519 DO irow = 1, nrow_global
520 IF (ipivot(irow) .NE. irow) counter = counter + 1
521 determinant = determinant*a(irow, irow)
523 IF (mod(counter, 2) == 1) determinant = -1.0_dp*determinant
530 CALL timestop(handle)
560 SUBROUTINE cp_cfm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, &
561 matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, &
563 CHARACTER(len=1),
INTENT(in) :: transa, transb
564 INTEGER,
INTENT(in) :: m, n, k
565 COMPLEX(kind=dp),
INTENT(in) :: alpha
566 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_a, matrix_b
567 COMPLEX(kind=dp),
INTENT(in) :: beta
569 INTEGER,
INTENT(in),
OPTIONAL :: a_first_col, a_first_row, b_first_col, &
570 b_first_row, c_first_col, c_first_row
572 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_gemm'
574 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, b, c
575 INTEGER :: handle, i_a, i_b, i_c, j_a, j_b, j_c
576#if defined(__parallel)
577 INTEGER,
DIMENSION(9) :: desca, descb, descc
579 INTEGER :: lda, ldb, ldc
582 CALL timeset(routinen, handle)
583 a => matrix_a%local_data
584 b => matrix_b%local_data
585 c => matrix_c%local_data
588 IF (
PRESENT(a_first_row)) i_a = a_first_row
591 IF (
PRESENT(a_first_col)) j_a = a_first_col
594 IF (
PRESENT(b_first_row)) i_b = b_first_row
597 IF (
PRESENT(b_first_col)) j_b = b_first_col
600 IF (
PRESENT(c_first_row)) i_c = c_first_row
603 IF (
PRESENT(c_first_col)) j_c = c_first_col
605#if defined(__parallel)
606 desca(:) = matrix_a%matrix_struct%descriptor(:)
607 descb(:) = matrix_b%matrix_struct%descriptor(:)
608 descc(:) = matrix_c%matrix_struct%descriptor(:)
610 CALL pzgemm(transa, transb, m, n, k, alpha, a(1, 1), i_a, j_a, desca, &
611 b(1, 1), i_b, j_b, descb, beta, c(1, 1), i_c, j_c, descc)
618 CALL zgemm(transa, transb, m, n, k, alpha, a(i_a, j_a), &
619 lda, b(i_b, j_b), ldb, beta, c(i_c, j_c), ldc)
621 CALL timestop(handle)
634 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in) :: scaling
636 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_column_scale'
638 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
639 INTEGER :: handle, icol_local, ncol_local, &
641#if defined(__parallel)
642 INTEGER,
DIMENSION(:),
POINTER :: col_indices
645 CALL timeset(routinen, handle)
647 a => matrix_a%local_data
649#if defined(__parallel)
650 CALL cp_cfm_get_info(matrix_a, nrow_local=nrow_local, ncol_local=ncol_local, col_indices=col_indices)
651 ncol_local = min(ncol_local,
SIZE(scaling))
653 DO icol_local = 1, ncol_local
654 CALL zscal(nrow_local, scaling(col_indices(icol_local)), a(1, icol_local), 1)
657 nrow_local =
SIZE(a, 1)
658 ncol_local = min(
SIZE(a, 2),
SIZE(scaling))
660 DO icol_local = 1, ncol_local
661 CALL zscal(nrow_local, scaling(icol_local), a(1, icol_local), 1)
665 CALL timestop(handle)
674 SUBROUTINE cp_cfm_dscale(alpha, matrix_a)
675 REAL(kind=
dp),
INTENT(in) :: alpha
678 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_dscale'
680 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
683 CALL timeset(routinen, handle)
687 a => matrix_a%local_data
689 CALL zdscal(
SIZE(a), alpha, a(1, 1), 1)
691 CALL timestop(handle)
692 END SUBROUTINE cp_cfm_dscale
702 SUBROUTINE cp_cfm_zscale(alpha, matrix_a)
703 COMPLEX(kind=dp),
INTENT(in) :: alpha
706 CHARACTER(len=*),
PARAMETER :: routineN =
'cp_cfm_zscale'
708 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
711 CALL timeset(routinen, handle)
715 a => matrix_a%local_data
717 CALL zscal(
SIZE(a), alpha, a(1, 1), 1)
719 CALL timestop(handle)
720 END SUBROUTINE cp_cfm_zscale
732 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_a, general_a
733 COMPLEX(kind=dp),
OPTIONAL :: determinant
735 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_solve'
737 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, a_general
738 INTEGER :: counter, handle, info, irow, nrow_global
739 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
741#if defined(__parallel)
742 INTEGER :: icol, ncol_local, nrow_local
743 INTEGER,
DIMENSION(9) :: desca, descb
744 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
749 CALL timeset(routinen, handle)
751 a => matrix_a%local_data
752 a_general => general_a%local_data
753 nrow_global = matrix_a%matrix_struct%nrow_global
754 ALLOCATE (ipivot(nrow_global))
756#if defined(__parallel)
757 desca(:) = matrix_a%matrix_struct%descriptor(:)
758 descb(:) = general_a%matrix_struct%descriptor(:)
759 CALL pzgetrf(nrow_global, nrow_global, a(1, 1), 1, 1, desca, ipivot, info)
760 IF (
PRESENT(determinant))
THEN
761 CALL cp_cfm_get_info(matrix_a, nrow_local=nrow_local, ncol_local=ncol_local, &
762 row_indices=row_indices, col_indices=col_indices)
765 DO irow = 1, nrow_local
766 IF (ipivot(irow) .NE. row_indices(irow)) counter = counter + 1
769 IF (mod(counter, 2) == 0)
THEN
778 DO WHILE (irow <= nrow_local .AND. icol <= ncol_local)
779 IF (row_indices(irow) < col_indices(icol))
THEN
781 ELSE IF (row_indices(irow) > col_indices(icol))
THEN
784 determinant = determinant*a(irow, icol)
789 CALL matrix_a%matrix_struct%para_env%prod(determinant)
792 CALL pzgetrs(
"N", nrow_global, nrow_global, a(1, 1), 1, 1, desca, &
793 ipivot, a_general(1, 1), 1, 1, descb, info)
796 ldb =
SIZE(a_general, 1)
797 CALL zgetrf(nrow_global, nrow_global, a(1, 1), lda, ipivot, info)
798 IF (
PRESENT(determinant))
THEN
801 DO irow = 1, nrow_global
802 IF (ipivot(irow) .NE. irow) counter = counter + 1
803 determinant = determinant*a(irow, irow)
805 IF (mod(counter, 2) == 1) determinant = -1.0_dp*determinant
807 CALL zgetrs(
"N", nrow_global, nrow_global, a(1, 1), lda, ipivot, a_general(1, 1), ldb, info)
813 CALL timestop(handle)
825 INTEGER,
INTENT(out),
OPTIONAL :: info_out
827 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_lu_invert'
829 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: work
830 COMPLEX(kind=dp),
DIMENSION(1) :: work1
831 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: mat
832 INTEGER :: handle, info, lwork, nrows_global
833 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
835#if defined(__parallel)
837 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iwork
838 INTEGER,
DIMENSION(1) :: iwork1
839 INTEGER,
DIMENSION(9) :: desca
844 CALL timeset(routinen, handle)
846 mat => matrix%local_data
847 nrows_global = matrix%matrix_struct%nrow_global
848 cpassert(nrows_global .EQ. matrix%matrix_struct%ncol_global)
849 ALLOCATE (ipivot(nrows_global))
852#if defined(__parallel)
853 desca = matrix%matrix_struct%descriptor
854 CALL pzgetrf(nrows_global, nrows_global, &
855 mat(1, 1), 1, 1, desca, ipivot, info)
858 CALL zgetrf(nrows_global, nrows_global, &
859 mat(1, 1), lda, ipivot, info)
862 CALL cp_abort(__location__,
"LU decomposition has failed")
866#if defined(__parallel)
867 CALL pzgetri(nrows_global, mat(1, 1), 1, 1, desca, &
868 ipivot, work1, -1, iwork1, -1, info)
869 lwork = int(work1(1))
870 liwork = int(iwork1(1))
871 ALLOCATE (work(lwork))
872 ALLOCATE (iwork(liwork))
873 CALL pzgetri(nrows_global, mat(1, 1), 1, 1, desca, &
874 ipivot, work, lwork, iwork, liwork, info)
877 CALL zgetri(nrows_global, mat(1, 1), lda, ipivot, work1, -1, info)
878 lwork = int(work1(1))
879 ALLOCATE (work(lwork))
880 CALL zgetri(nrows_global, mat(1, 1), lda, ipivot, work, lwork, info)
885 IF (
PRESENT(info_out))
THEN
889 CALL cp_abort(__location__,
"LU inversion has failed")
892 CALL timestop(handle)
909 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_a, matrix_b
910 COMPLEX(kind=dp),
INTENT(out) :: trace
912 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_trace'
914 INTEGER :: handle, mypcol, myprow, ncol_local, &
915 npcol, nprow, nrow_local
919 CALL timeset(routinen, handle)
921 context => matrix_a%matrix_struct%context
922 myprow = context%mepos(1)
923 mypcol = context%mepos(2)
924 nprow = context%num_pe(1)
925 npcol = context%num_pe(2)
927 group = matrix_a%matrix_struct%para_env
929 nrow_local = min(matrix_a%matrix_struct%nrow_locals(myprow), matrix_b%matrix_struct%nrow_locals(myprow))
930 ncol_local = min(matrix_a%matrix_struct%ncol_locals(mypcol), matrix_b%matrix_struct%ncol_locals(mypcol))
934 matrix_b%local_data(1:nrow_local, 1:ncol_local))
936 CALL group%sum(trace)
938 CALL timestop(handle)
977 transa_tr, invert_tr, uplo_tr, unit_diag_tr, n_rows, n_cols, &
979 TYPE(
cp_cfm_type),
INTENT(IN) :: triangular_matrix, matrix_b
980 CHARACTER,
INTENT(in),
OPTIONAL :: side, transa_tr
981 LOGICAL,
INTENT(in),
OPTIONAL :: invert_tr
982 CHARACTER,
INTENT(in),
OPTIONAL :: uplo_tr
983 LOGICAL,
INTENT(in),
OPTIONAL :: unit_diag_tr
984 INTEGER,
INTENT(in),
OPTIONAL :: n_rows, n_cols
985 COMPLEX(kind=dp),
INTENT(in),
OPTIONAL :: alpha
987 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_triangular_multiply'
989 CHARACTER :: side_char, transa, unit_diag, uplo
990 COMPLEX(kind=dp) :: al
991 INTEGER :: handle, m, n
994 CALL timeset(routinen, handle)
1000 al = cmplx(1.0_dp, 0.0_dp,
dp)
1002 IF (
PRESENT(side)) side_char = side
1003 IF (
PRESENT(invert_tr)) invert = invert_tr
1004 IF (
PRESENT(uplo_tr)) uplo = uplo_tr
1005 IF (
PRESENT(unit_diag_tr))
THEN
1006 IF (unit_diag_tr)
THEN
1012 IF (
PRESENT(transa_tr)) transa = transa_tr
1013 IF (
PRESENT(alpha)) al = alpha
1014 IF (
PRESENT(n_rows)) m = n_rows
1015 IF (
PRESENT(n_cols)) n = n_cols
1019#if defined(__parallel)
1020 CALL pztrsm(side_char, uplo, transa, unit_diag, m, n, al, &
1021 triangular_matrix%local_data(1, 1), 1, 1, &
1022 triangular_matrix%matrix_struct%descriptor, &
1023 matrix_b%local_data(1, 1), 1, 1, &
1024 matrix_b%matrix_struct%descriptor(1))
1026 CALL ztrsm(side_char, uplo, transa, unit_diag, m, n, al, &
1027 triangular_matrix%local_data(1, 1), &
1028 SIZE(triangular_matrix%local_data, 1), &
1029 matrix_b%local_data(1, 1),
SIZE(matrix_b%local_data, 1))
1034#if defined(__parallel)
1035 CALL pztrmm(side_char, uplo, transa, unit_diag, m, n, al, &
1036 triangular_matrix%local_data(1, 1), 1, 1, &
1037 triangular_matrix%matrix_struct%descriptor, &
1038 matrix_b%local_data(1, 1), 1, 1, &
1039 matrix_b%matrix_struct%descriptor(1))
1041 CALL ztrmm(side_char, uplo, transa, unit_diag, m, n, al, &
1042 triangular_matrix%local_data(1, 1), &
1043 SIZE(triangular_matrix%local_data, 1), &
1044 matrix_b%local_data(1, 1),
SIZE(matrix_b%local_data, 1))
1049 CALL timestop(handle)
1062 CHARACTER,
INTENT(in),
OPTIONAL :: uplo
1063 INTEGER,
INTENT(out),
OPTIONAL :: info_out
1065 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_triangular_invert'
1067 CHARACTER :: unit_diag, my_uplo
1068 INTEGER :: handle, info, ncol_global
1069 COMPLEX(kind=dp),
DIMENSION(:, :), &
1071#if defined(__parallel)
1072 INTEGER,
DIMENSION(9) :: desca
1075 CALL timeset(routinen, handle)
1079 IF (
PRESENT(uplo)) my_uplo = uplo
1081 ncol_global = matrix_a%matrix_struct%ncol_global
1083 a => matrix_a%local_data
1085#if defined(__parallel)
1086 desca(:) = matrix_a%matrix_struct%descriptor(:)
1087 CALL pztrtri(my_uplo, unit_diag, ncol_global, a(1, 1), 1, 1, desca, info)
1089 CALL ztrtri(my_uplo, unit_diag, ncol_global, a(1, 1), ncol_global, info)
1092 IF (
PRESENT(info_out))
THEN
1096 CALL cp_abort(__location__, &
1097 "triangular invert failed: matrix is not positive definite or ill-conditioned")
1100 CALL timestop(handle)
1112 CHARACTER,
INTENT(in) :: trans
1115 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_transpose'
1117 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: aa, cc
1118 INTEGER :: handle, ncol_global, nrow_global
1119#if defined(__parallel)
1120 INTEGER,
DIMENSION(9) :: desca, descc
1121#elif !defined(__MKL)
1125 CALL timeset(routinen, handle)
1127 nrow_global = matrix%matrix_struct%nrow_global
1128 ncol_global = matrix%matrix_struct%ncol_global
1130 cpassert(matrixt%matrix_struct%nrow_global == ncol_global)
1131 cpassert(matrixt%matrix_struct%ncol_global == nrow_global)
1133 aa => matrix%local_data
1134 cc => matrixt%local_data
1136#if defined(__parallel)
1137 desca = matrix%matrix_struct%descriptor
1138 descc = matrixt%matrix_struct%descriptor
1141 CALL pztranu(nrow_global, ncol_global, &
1142 z_one, aa(1, 1), 1, 1, desca, &
1143 z_zero, cc(1, 1), 1, 1, descc)
1145 CALL pztranc(nrow_global, ncol_global, &
1146 z_one, aa(1, 1), 1, 1, desca, &
1147 z_zero, cc(1, 1), 1, 1, descc)
1149 cpabort(
"trans only accepts 'T' or 'C'")
1152 CALL mkl_zomatcopy(
'C', trans, nrow_global, ncol_global, 1.0_dp, aa(1, 1), nrow_global, cc(1, 1), ncol_global)
1156 DO jj = 1, ncol_global
1157 DO ii = 1, nrow_global
1158 cc(ii, jj) = aa(jj, ii)
1162 DO jj = 1, ncol_global
1163 DO ii = 1, nrow_global
1164 cc(ii, jj) = conjg(aa(jj, ii))
1168 cpabort(
"trans only accepts 'T' or 'C'")
1172 CALL timestop(handle)
1187 CHARACTER,
INTENT(IN) :: mode
1188 REAL(kind=
dp) :: res
1190 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_norm'
1192 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: aa
1193 INTEGER :: handle, lwork, ncols, ncols_local, &
1195 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work
1197#if defined(__parallel)
1198 INTEGER,
DIMENSION(9) :: desca
1203 CALL timeset(routinen, handle)
1206 nrow_global=nrows, &
1207 ncol_global=ncols, &
1208 nrow_local=nrows_local, &
1209 ncol_local=ncols_local)
1210 aa => matrix%local_data
1215 CASE (
'1',
'O',
'o')
1216#if defined(__parallel)
1222#if defined(__parallel)
1227 CASE (
'F',
'f',
'E',
'e')
1230 cpabort(
"mode input is not valid")
1233 ALLOCATE (work(lwork))
1235#if defined(__parallel)
1236 desca = matrix%matrix_struct%descriptor
1237 res = pzlange(mode, nrows, ncols, aa(1, 1), 1, 1, desca, work)
1240 res = zlange(mode, nrows, ncols, aa(1, 1), lda, work)
1244 CALL timestop(handle)
1258 INTEGER,
INTENT(IN) :: irow, jrow
1259 REAL(
dp),
INTENT(IN) :: cs, sn
1261 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_rot_rows'
1262 INTEGER :: handle, nrow, ncol
1263 COMPLEX(KIND=dp) :: sn_cmplx
1265#if defined(__parallel)
1266 INTEGER :: info, lwork
1267 INTEGER,
DIMENSION(9) :: desc
1268 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: work
1271 CALL timeset(routinen, handle)
1273 sn_cmplx = cmplx(sn, 0.0_dp,
dp)
1275#if defined(__parallel)
1277 ALLOCATE (work(lwork))
1278 desc(:) = matrix%matrix_struct%descriptor(:)
1280 matrix%local_data(1, 1), irow, 1, desc, ncol, &
1281 matrix%local_data(1, 1), jrow, 1, desc, ncol, &
1282 cs, sn_cmplx, work, lwork, info)
1286 CALL zrot(ncol, matrix%local_data(irow, 1), ncol, matrix%local_data(jrow, 1), ncol, cs, sn_cmplx)
1289 CALL timestop(handle)
1303 INTEGER,
INTENT(IN) :: icol, jcol
1304 REAL(
dp),
INTENT(IN) :: cs, sn
1306 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_rot_cols'
1307 INTEGER :: handle, nrow, ncol
1308 COMPLEX(KIND=dp) :: sn_cmplx
1310#if defined(__parallel)
1311 INTEGER :: info, lwork
1312 INTEGER,
DIMENSION(9) :: desc
1313 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: work
1316 CALL timeset(routinen, handle)
1318 sn_cmplx = cmplx(sn, 0.0_dp,
dp)
1320#if defined(__parallel)
1322 ALLOCATE (work(lwork))
1323 desc(:) = matrix%matrix_struct%descriptor(:)
1325 matrix%local_data(1, 1), 1, icol, desc, 1, &
1326 matrix%local_data(1, 1), 1, jcol, desc, 1, &
1327 cs, sn_cmplx, work, lwork, info)
1331 CALL zrot(nrow, matrix%local_data(1, icol), 1, matrix%local_data(1, jcol), 1, cs, sn_cmplx)
1334 CALL timestop(handle)
1349 TYPE(
cp_cfm_type),
INTENT(IN),
OPTIONAL :: workspace
1350 CHARACTER,
INTENT(IN),
OPTIONAL :: uplo
1352 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_cfm_uplo_to_full'
1355 INTEGER :: handle, i_global, iib, j_global, jjb, &
1356 ncol_local, nrow_local
1357 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1360 CALL timeset(routinen, handle)
1362 IF (.NOT.
PRESENT(workspace))
THEN
1369 IF (
PRESENT(uplo)) myuplo = uplo
1373 nrow_local=nrow_local, &
1374 ncol_local=ncol_local, &
1375 row_indices=row_indices, &
1376 col_indices=col_indices)
1378 DO jjb = 1, ncol_local
1379 j_global = col_indices(jjb)
1380 DO iib = 1, nrow_local
1381 i_global = row_indices(iib)
1382 IF (merge(j_global < i_global, j_global > i_global, (myuplo ==
"U") .OR. (myuplo ==
"u")))
THEN
1383 matrix%local_data(iib, jjb) =
z_zero
1384 ELSE IF (j_global == i_global)
THEN
1385 matrix%local_data(iib, jjb) = matrix%local_data(iib, jjb)/(2.0_dp, 0.0_dp)
1394 IF (.NOT.
PRESENT(workspace))
THEN
1398 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_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_uplo_to_full(matrix, workspace, uplo)
...
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.