27 #include "../base/base_uses.f90"
32 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
33 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cp_cfm_basic_linalg'
54 REAL(kind=
dp),
EXTERNAL :: zlange, pzlange
56 INTERFACE cp_cfm_scale
57 MODULE PROCEDURE cp_cfm_dscale, cp_cfm_zscale
58 END INTERFACE cp_cfm_scale
72 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_a, matrix_b, matrix_c
74 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_schur_product'
76 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, b, c
77 INTEGER :: handle, icol_local, irow_local, mypcol, &
78 myprow, ncol_local, nrow_local
80 CALL timeset(routinen, handle)
82 myprow = matrix_a%matrix_struct%context%mepos(1)
83 mypcol = matrix_a%matrix_struct%context%mepos(2)
85 a => matrix_a%local_data
86 b => matrix_b%local_data
87 c => matrix_c%local_data
89 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
90 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
92 DO icol_local = 1, ncol_local
93 DO irow_local = 1, nrow_local
94 c(irow_local, icol_local) = a(irow_local, icol_local)*b(irow_local, icol_local)
108 SUBROUTINE cp_cfm_schur_product_cc(matrix_a, matrix_b, matrix_c)
110 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_a, matrix_b, matrix_c
112 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_schur_product_cc'
114 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, b, c
115 INTEGER :: handle, icol_local, irow_local, mypcol, &
116 myprow, ncol_local, nrow_local
118 CALL timeset(routinen, handle)
120 myprow = matrix_a%matrix_struct%context%mepos(1)
121 mypcol = matrix_a%matrix_struct%context%mepos(2)
123 a => matrix_a%local_data
124 b => matrix_b%local_data
125 c => matrix_c%local_data
127 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
128 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
130 DO icol_local = 1, ncol_local
131 DO irow_local = 1, nrow_local
132 c(irow_local, icol_local) = a(irow_local, icol_local)*conjg(b(irow_local, icol_local))
136 CALL timestop(handle)
138 END SUBROUTINE cp_cfm_schur_product_cc
158 COMPLEX(kind=dp),
INTENT(in) :: alpha
159 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_a
160 COMPLEX(kind=dp),
INTENT(in),
OPTIONAL :: beta
161 TYPE(cp_cfm_type),
INTENT(IN),
OPTIONAL :: matrix_b
163 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_scale_and_add'
165 COMPLEX(kind=dp) :: my_beta
166 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, b
167 INTEGER :: handle, icol_local, irow_local, mypcol, &
168 myprow, ncol_local, nrow_local
170 CALL timeset(routinen, handle)
173 IF (
PRESENT(beta)) my_beta = beta
177 myprow = matrix_a%matrix_struct%context%mepos(1)
178 mypcol = matrix_a%matrix_struct%context%mepos(2)
180 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
181 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
183 a => matrix_a%local_data
185 IF (my_beta ==
z_zero)
THEN
189 ELSE IF (alpha ==
z_one)
THEN
190 CALL timestop(handle)
193 a(:, :) = alpha*a(:, :)
197 cpassert(
PRESENT(matrix_b))
198 IF (matrix_a%matrix_struct%context /= matrix_b%matrix_struct%context) &
199 cpabort(
"matrixes must be in the same blacs context")
202 matrix_b%matrix_struct))
THEN
204 b => matrix_b%local_data
207 IF (my_beta ==
z_one)
THEN
209 DO icol_local = 1, ncol_local
210 DO irow_local = 1, nrow_local
211 a(irow_local, icol_local) = b(irow_local, icol_local)
216 DO icol_local = 1, ncol_local
217 DO irow_local = 1, nrow_local
218 a(irow_local, icol_local) = my_beta*b(irow_local, icol_local)
222 ELSE IF (alpha ==
z_one)
THEN
223 IF (my_beta ==
z_one)
THEN
225 DO icol_local = 1, ncol_local
226 DO irow_local = 1, nrow_local
227 a(irow_local, icol_local) = a(irow_local, icol_local) + b(irow_local, icol_local)
232 DO icol_local = 1, ncol_local
233 DO irow_local = 1, nrow_local
234 a(irow_local, icol_local) = a(irow_local, icol_local) + my_beta*b(irow_local, icol_local)
240 DO icol_local = 1, ncol_local
241 DO irow_local = 1, nrow_local
242 a(irow_local, icol_local) = alpha*a(irow_local, icol_local) + my_beta*b(irow_local, icol_local)
247 #if defined(__SCALAPACK)
248 cpabort(
"to do (pdscal,pdcopy,pdaxpy)")
254 CALL timestop(handle)
269 COMPLEX(kind=dp),
INTENT(in) :: alpha
270 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_a
271 COMPLEX(kind=dp),
INTENT(in) :: beta
272 TYPE(cp_fm_type),
INTENT(IN) :: matrix_b
274 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_scale_and_add_fm'
276 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
277 INTEGER :: handle, icol_local, irow_local, mypcol, &
278 myprow, ncol_local, nrow_local
279 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: b
281 CALL timeset(routinen, handle)
285 myprow = matrix_a%matrix_struct%context%mepos(1)
286 mypcol = matrix_a%matrix_struct%context%mepos(2)
288 nrow_local = matrix_a%matrix_struct%nrow_locals(myprow)
289 ncol_local = matrix_a%matrix_struct%ncol_locals(mypcol)
291 a => matrix_a%local_data
297 ELSE IF (alpha ==
z_one)
THEN
298 CALL timestop(handle)
301 a(:, :) = alpha*a(:, :)
305 IF (matrix_a%matrix_struct%context /= matrix_b%matrix_struct%context) &
306 cpabort(
"matrices must be in the same blacs context")
309 matrix_b%matrix_struct))
THEN
311 b => matrix_b%local_data
314 IF (beta ==
z_one)
THEN
316 DO icol_local = 1, ncol_local
317 DO irow_local = 1, nrow_local
318 a(irow_local, icol_local) = b(irow_local, icol_local)
323 DO icol_local = 1, ncol_local
324 DO irow_local = 1, nrow_local
325 a(irow_local, icol_local) = beta*b(irow_local, icol_local)
329 ELSE IF (alpha ==
z_one)
THEN
330 IF (beta ==
z_one)
THEN
332 DO icol_local = 1, ncol_local
333 DO irow_local = 1, nrow_local
334 a(irow_local, icol_local) = a(irow_local, icol_local) + b(irow_local, icol_local)
339 DO icol_local = 1, ncol_local
340 DO irow_local = 1, nrow_local
341 a(irow_local, icol_local) = a(irow_local, icol_local) + beta*b(irow_local, icol_local)
347 DO icol_local = 1, ncol_local
348 DO irow_local = 1, nrow_local
349 a(irow_local, icol_local) = alpha*a(irow_local, icol_local) + beta*b(irow_local, icol_local)
354 #if defined(__SCALAPACK)
355 cpabort(
"to do (pdscal,pdcopy,pdaxpy)")
361 CALL timestop(handle)
376 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_a
377 COMPLEX(kind=dp),
INTENT(out) :: determinant
379 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_lu_decompose'
381 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
382 INTEGER :: counter, handle, info, irow, nrow_global
383 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
385 #if defined(__SCALAPACK)
386 INTEGER :: icol, ncol_local, nrow_local
387 INTEGER,
DIMENSION(9) :: desca
388 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
393 CALL timeset(routinen, handle)
395 nrow_global = matrix_a%matrix_struct%nrow_global
396 a => matrix_a%local_data
398 ALLOCATE (ipivot(nrow_global))
399 #if defined(__SCALAPACK)
400 CALL cp_cfm_get_info(matrix_a, nrow_local=nrow_local, ncol_local=ncol_local, &
401 row_indices=row_indices, col_indices=col_indices)
403 desca(:) = matrix_a%matrix_struct%descriptor(:)
404 CALL pzgetrf(nrow_global, nrow_global, a(1, 1), 1, 1, desca, ipivot, info)
407 DO irow = 1, nrow_local
408 IF (ipivot(irow) .NE. row_indices(irow)) counter = counter + 1
411 IF (mod(counter, 2) == 0)
THEN
420 DO WHILE (irow <= nrow_local .AND. icol <= ncol_local)
421 IF (row_indices(irow) < col_indices(icol))
THEN
423 ELSE IF (row_indices(irow) > col_indices(icol))
THEN
426 determinant = determinant*a(irow, icol)
431 CALL matrix_a%matrix_struct%para_env%prod(determinant)
434 CALL zgetrf(nrow_global, nrow_global, a(1, 1), lda, ipivot, info)
437 DO irow = 1, nrow_global
438 IF (ipivot(irow) .NE. irow) counter = counter + 1
439 determinant = determinant*a(irow, irow)
441 IF (mod(counter, 2) == 1) determinant = -1.0_dp*determinant
448 CALL timestop(handle)
478 SUBROUTINE cp_cfm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, &
479 matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, &
481 CHARACTER(len=1),
INTENT(in) :: transa, transb
482 INTEGER,
INTENT(in) :: m, n, k
483 COMPLEX(kind=dp),
INTENT(in) :: alpha
484 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_a, matrix_b
485 COMPLEX(kind=dp),
INTENT(in) :: beta
486 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_c
487 INTEGER,
INTENT(in),
OPTIONAL :: a_first_col, a_first_row, b_first_col, &
488 b_first_row, c_first_col, c_first_row
490 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_gemm'
492 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, b, c
493 INTEGER :: handle, i_a, i_b, i_c, j_a, j_b, j_c
494 #if defined(__SCALAPACK)
495 INTEGER,
DIMENSION(9) :: desca, descb, descc
497 INTEGER :: lda, ldb, ldc
500 CALL timeset(routinen, handle)
501 a => matrix_a%local_data
502 b => matrix_b%local_data
503 c => matrix_c%local_data
505 IF (
PRESENT(a_first_row))
THEN
510 IF (
PRESENT(a_first_col))
THEN
515 IF (
PRESENT(b_first_row))
THEN
520 IF (
PRESENT(b_first_col))
THEN
525 IF (
PRESENT(c_first_row))
THEN
530 IF (
PRESENT(c_first_col))
THEN
536 #if defined(__SCALAPACK)
537 desca(:) = matrix_a%matrix_struct%descriptor(:)
538 descb(:) = matrix_b%matrix_struct%descriptor(:)
539 descc(:) = matrix_c%matrix_struct%descriptor(:)
541 CALL pzgemm(transa, transb, m, n, k, alpha, a(1, 1), i_a, j_a, desca, &
542 b(1, 1), i_b, j_b, descb, beta, c(1, 1), i_c, j_c, descc)
548 CALL zgemm(transa, transb, m, n, k, alpha, a(i_a, j_a), &
549 lda, b(i_b, j_b), ldb, beta, c(i_c, j_c), ldc)
551 CALL timestop(handle)
563 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_a
564 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in) :: scaling
566 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_column_scale'
568 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
569 INTEGER :: handle, icol_local, ncol_local, &
571 #if defined(__SCALAPACK)
572 INTEGER,
DIMENSION(:),
POINTER :: col_indices
575 CALL timeset(routinen, handle)
577 a => matrix_a%local_data
579 #if defined(__SCALAPACK)
580 CALL cp_cfm_get_info(matrix_a, nrow_local=nrow_local, ncol_local=ncol_local, col_indices=col_indices)
581 ncol_local = min(ncol_local,
SIZE(scaling))
583 DO icol_local = 1, ncol_local
584 CALL zscal(nrow_local, scaling(col_indices(icol_local)), a(1, icol_local), 1)
587 nrow_local =
SIZE(a, 1)
588 ncol_local = min(
SIZE(a, 2),
SIZE(scaling))
590 DO icol_local = 1, ncol_local
591 CALL zscal(nrow_local, scaling(icol_local), a(1, icol_local), 1)
595 CALL timestop(handle)
604 SUBROUTINE cp_cfm_dscale(alpha, matrix_a)
605 REAL(kind=
dp),
INTENT(in) :: alpha
606 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_a
608 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_dscale'
610 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
613 CALL timeset(routinen, handle)
617 a => matrix_a%local_data
619 CALL zdscal(
SIZE(a), alpha, a(1, 1), 1)
621 CALL timestop(handle)
622 END SUBROUTINE cp_cfm_dscale
632 SUBROUTINE cp_cfm_zscale(alpha, matrix_a)
633 COMPLEX(kind=dp),
INTENT(in) :: alpha
634 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_a
636 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_zscale'
638 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
641 CALL timeset(routinen, handle)
645 a => matrix_a%local_data
647 CALL zscal(
SIZE(a), alpha, a(1, 1), 1)
649 CALL timestop(handle)
650 END SUBROUTINE cp_cfm_zscale
662 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_a, general_a
663 COMPLEX(kind=dp),
OPTIONAL :: determinant
665 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_solve'
667 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a, a_general
668 INTEGER :: counter, handle, info, irow, nrow_global
669 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
671 #if defined(__SCALAPACK)
672 INTEGER :: icol, ncol_local, nrow_local
673 INTEGER,
DIMENSION(9) :: desca, descb
674 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
679 CALL timeset(routinen, handle)
681 a => matrix_a%local_data
682 a_general => general_a%local_data
683 nrow_global = matrix_a%matrix_struct%nrow_global
684 ALLOCATE (ipivot(nrow_global))
686 #if defined(__SCALAPACK)
687 desca(:) = matrix_a%matrix_struct%descriptor(:)
688 descb(:) = general_a%matrix_struct%descriptor(:)
689 CALL pzgetrf(nrow_global, nrow_global, a(1, 1), 1, 1, desca, ipivot, info)
690 IF (
PRESENT(determinant))
THEN
691 CALL cp_cfm_get_info(matrix_a, nrow_local=nrow_local, ncol_local=ncol_local, &
692 row_indices=row_indices, col_indices=col_indices)
695 DO irow = 1, nrow_local
696 IF (ipivot(irow) .NE. row_indices(irow)) counter = counter + 1
699 IF (mod(counter, 2) == 0)
THEN
708 DO WHILE (irow <= nrow_local .AND. icol <= ncol_local)
709 IF (row_indices(irow) < col_indices(icol))
THEN
711 ELSE IF (row_indices(irow) > col_indices(icol))
THEN
714 determinant = determinant*a(irow, icol)
719 CALL matrix_a%matrix_struct%para_env%prod(determinant)
722 CALL pzgetrs(
"N", nrow_global, nrow_global, a(1, 1), 1, 1, desca, &
723 ipivot, a_general(1, 1), 1, 1, descb, info)
726 ldb =
SIZE(a_general, 1)
727 CALL zgetrf(nrow_global, nrow_global, a(1, 1), lda, ipivot, info)
728 IF (
PRESENT(determinant))
THEN
731 DO irow = 1, nrow_global
732 IF (ipivot(irow) .NE. irow) counter = counter + 1
733 determinant = determinant*a(irow, irow)
735 IF (mod(counter, 2) == 1) determinant = -1.0_dp*determinant
737 CALL zgetrs(
"N", nrow_global, nrow_global, a(1, 1), lda, ipivot, a_general(1, 1), ldb, info)
743 CALL timestop(handle)
754 TYPE(cp_cfm_type),
INTENT(IN) :: matrix
755 INTEGER,
INTENT(out),
OPTIONAL :: info_out
757 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_lu_invert'
759 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: work
760 COMPLEX(kind=dp),
DIMENSION(1) :: work1
761 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: mat
762 INTEGER :: handle, info, lwork, nrows_global
763 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
765 #if defined(__SCALAPACK)
767 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iwork
768 INTEGER,
DIMENSION(1) :: iwork1
769 INTEGER,
DIMENSION(9) :: desca
774 CALL timeset(routinen, handle)
776 mat => matrix%local_data
777 nrows_global = matrix%matrix_struct%nrow_global
778 cpassert(nrows_global .EQ. matrix%matrix_struct%ncol_global)
779 ALLOCATE (ipivot(nrows_global))
782 #if defined(__SCALAPACK)
783 desca = matrix%matrix_struct%descriptor
784 CALL pzgetrf(nrows_global, nrows_global, &
785 mat(1, 1), 1, 1, desca, ipivot, info)
788 CALL zgetrf(nrows_global, nrows_global, &
789 mat(1, 1), lda, ipivot, info)
792 CALL cp_abort(__location__,
"LU decomposition has failed")
796 #if defined(__SCALAPACK)
797 CALL pzgetri(nrows_global, mat(1, 1), 1, 1, desca, &
798 ipivot, work1, -1, iwork1, -1, info)
799 lwork = int(work1(1))
800 liwork = int(iwork1(1))
801 ALLOCATE (work(lwork))
802 ALLOCATE (iwork(liwork))
803 CALL pzgetri(nrows_global, mat(1, 1), 1, 1, desca, &
804 ipivot, work, lwork, iwork, liwork, info)
807 CALL zgetri(nrows_global, mat(1, 1), lda, ipivot, work1, -1, info)
808 lwork = int(work1(1))
809 ALLOCATE (work(lwork))
810 CALL zgetri(nrows_global, mat(1, 1), lda, ipivot, work, lwork, info)
815 IF (
PRESENT(info_out))
THEN
819 CALL cp_abort(__location__,
"LU inversion has failed")
822 CALL timestop(handle)
840 TYPE(cp_cfm_type),
INTENT(IN) :: matrix
841 INTEGER,
INTENT(in),
OPTIONAL :: n
842 INTEGER,
INTENT(out),
OPTIONAL :: info_out
844 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_cholesky_decompose'
846 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: a
847 INTEGER :: handle, info, my_n
848 #if defined(__SCALAPACK)
849 INTEGER,
DIMENSION(9) :: desca
854 CALL timeset(routinen, handle)
856 my_n = min(matrix%matrix_struct%nrow_global, &
857 matrix%matrix_struct%ncol_global)
863 a => matrix%local_data
865 #if defined(__SCALAPACK)
866 desca(:) = matrix%matrix_struct%descriptor(:)
867 CALL pzpotrf(
'U', my_n, a(1, 1), 1, 1, desca, info)
870 CALL zpotrf(
'U', my_n, a(1, 1), lda, info)
873 IF (
PRESENT(info_out))
THEN
877 CALL cp_abort(__location__, &
878 "Cholesky decompose failed: matrix is not positive definite or ill-conditioned")
881 CALL timestop(handle)
896 TYPE(cp_cfm_type),
INTENT(IN) :: matrix
897 INTEGER,
INTENT(in),
OPTIONAL :: n
898 INTEGER,
INTENT(out),
OPTIONAL :: info_out
900 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_cholesky_invert'
901 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: aa
902 INTEGER :: info, handle
904 #if defined(__SCALAPACK)
905 INTEGER,
DIMENSION(9) :: desca
908 CALL timeset(routinen, handle)
910 my_n = min(matrix%matrix_struct%nrow_global, &
911 matrix%matrix_struct%ncol_global)
917 aa => matrix%local_data
919 #if defined(__SCALAPACK)
920 desca = matrix%matrix_struct%descriptor
921 CALL pzpotri(
'U', my_n, aa(1, 1), 1, 1, desca, info)
923 CALL zpotri(
'U', my_n, aa(1, 1),
SIZE(aa, 1), info)
926 IF (
PRESENT(info_out))
THEN
930 CALL cp_abort(__location__, &
931 "Cholesky invert failed: the matrix is not positive definite or ill-conditioned.")
934 CALL timestop(handle)
951 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_a, matrix_b
952 COMPLEX(kind=dp),
INTENT(out) :: trace
954 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_trace'
956 INTEGER :: handle, mypcol, myprow, ncol_local, &
957 npcol, nprow, nrow_local
958 TYPE(cp_blacs_env_type),
POINTER :: context
959 TYPE(mp_comm_type) :: group
961 CALL timeset(routinen, handle)
963 context => matrix_a%matrix_struct%context
964 myprow = context%mepos(1)
965 mypcol = context%mepos(2)
966 nprow = context%num_pe(1)
967 npcol = context%num_pe(2)
969 group = matrix_a%matrix_struct%para_env
971 nrow_local = min(matrix_a%matrix_struct%nrow_locals(myprow), matrix_b%matrix_struct%nrow_locals(myprow))
972 ncol_local = min(matrix_a%matrix_struct%ncol_locals(mypcol), matrix_b%matrix_struct%ncol_locals(mypcol))
975 trace = accurate_dot_product(matrix_a%local_data(1:nrow_local, 1:ncol_local), &
976 matrix_b%local_data(1:nrow_local, 1:ncol_local))
978 CALL group%sum(trace)
980 CALL timestop(handle)
1019 transa_tr, invert_tr, uplo_tr, unit_diag_tr, n_rows, n_cols, &
1021 TYPE(cp_cfm_type),
INTENT(IN) :: triangular_matrix, matrix_b
1022 CHARACTER,
INTENT(in),
OPTIONAL :: side, transa_tr
1023 LOGICAL,
INTENT(in),
OPTIONAL :: invert_tr
1024 CHARACTER,
INTENT(in),
OPTIONAL :: uplo_tr
1025 LOGICAL,
INTENT(in),
OPTIONAL :: unit_diag_tr
1026 INTEGER,
INTENT(in),
OPTIONAL :: n_rows, n_cols
1027 COMPLEX(kind=dp),
INTENT(in),
OPTIONAL :: alpha
1029 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_triangular_multiply'
1031 CHARACTER :: side_char, transa, unit_diag, uplo
1032 COMPLEX(kind=dp) :: al
1033 INTEGER :: handle, m, n
1036 CALL timeset(routinen, handle)
1042 al = cmplx(1.0_dp, 0.0_dp,
dp)
1044 IF (
PRESENT(side)) side_char = side
1045 IF (
PRESENT(invert_tr)) invert = invert_tr
1046 IF (
PRESENT(uplo_tr)) uplo = uplo_tr
1047 IF (
PRESENT(unit_diag_tr))
THEN
1048 IF (unit_diag_tr)
THEN
1054 IF (
PRESENT(transa_tr)) transa = transa_tr
1055 IF (
PRESENT(alpha)) al = alpha
1056 IF (
PRESENT(n_rows)) m = n_rows
1057 IF (
PRESENT(n_cols)) n = n_cols
1061 #if defined(__SCALAPACK)
1062 CALL pztrsm(side_char, uplo, transa, unit_diag, m, n, al, &
1063 triangular_matrix%local_data(1, 1), 1, 1, &
1064 triangular_matrix%matrix_struct%descriptor, &
1065 matrix_b%local_data(1, 1), 1, 1, &
1066 matrix_b%matrix_struct%descriptor(1))
1068 CALL ztrsm(side_char, uplo, transa, unit_diag, m, n, al, &
1069 triangular_matrix%local_data(1, 1), &
1070 SIZE(triangular_matrix%local_data, 1), &
1071 matrix_b%local_data(1, 1),
SIZE(matrix_b%local_data, 1))
1076 #if defined(__SCALAPACK)
1077 CALL pztrmm(side_char, uplo, transa, unit_diag, m, n, al, &
1078 triangular_matrix%local_data(1, 1), 1, 1, &
1079 triangular_matrix%matrix_struct%descriptor, &
1080 matrix_b%local_data(1, 1), 1, 1, &
1081 matrix_b%matrix_struct%descriptor(1))
1083 CALL ztrmm(side_char, uplo, transa, unit_diag, m, n, al, &
1084 triangular_matrix%local_data(1, 1), &
1085 SIZE(triangular_matrix%local_data, 1), &
1086 matrix_b%local_data(1, 1),
SIZE(matrix_b%local_data, 1))
1091 CALL timestop(handle)
1103 TYPE(cp_cfm_type),
INTENT(IN) :: matrix_a
1104 CHARACTER,
INTENT(in),
OPTIONAL :: uplo
1105 INTEGER,
INTENT(out),
OPTIONAL :: info_out
1107 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_triangular_invert'
1109 CHARACTER :: unit_diag, my_uplo
1110 INTEGER :: handle, info, ncol_global
1111 COMPLEX(kind=dp),
DIMENSION(:, :), &
1113 #if defined(__SCALAPACK)
1114 INTEGER,
DIMENSION(9) :: desca
1117 CALL timeset(routinen, handle)
1121 IF (
PRESENT(uplo)) my_uplo = uplo
1123 ncol_global = matrix_a%matrix_struct%ncol_global
1125 a => matrix_a%local_data
1127 #if defined(__SCALAPACK)
1128 desca(:) = matrix_a%matrix_struct%descriptor(:)
1129 CALL pztrtri(my_uplo, unit_diag, ncol_global, a(1, 1), 1, 1, desca, info)
1131 CALL ztrtri(my_uplo, unit_diag, ncol_global, a(1, 1), ncol_global, info)
1134 IF (
PRESENT(info_out))
THEN
1138 CALL cp_abort(__location__, &
1139 "triangular invert failed: matrix is not positive definite or ill-conditioned")
1142 CALL timestop(handle)
1153 TYPE(cp_cfm_type),
INTENT(IN) :: matrix
1154 CHARACTER,
INTENT(in) :: trans
1155 TYPE(cp_cfm_type),
INTENT(IN) :: matrixt
1157 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_transpose'
1159 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: aa, cc
1160 INTEGER :: handle, ncol_global, nrow_global
1161 #if defined(__SCALAPACK)
1162 INTEGER,
DIMENSION(9) :: desca, descc
1167 CALL timeset(routinen, handle)
1169 nrow_global = matrix%matrix_struct%nrow_global
1170 ncol_global = matrix%matrix_struct%ncol_global
1172 cpassert(matrixt%matrix_struct%nrow_global == ncol_global)
1173 cpassert(matrixt%matrix_struct%ncol_global == nrow_global)
1175 aa => matrix%local_data
1176 cc => matrixt%local_data
1178 #if defined(__SCALAPACK)
1179 desca = matrix%matrix_struct%descriptor
1180 descc = matrixt%matrix_struct%descriptor
1183 CALL pztranu(nrow_global, ncol_global, &
1184 z_one, aa(1, 1), 1, 1, desca, &
1185 z_zero, cc(1, 1), 1, 1, descc)
1187 CALL pztranc(nrow_global, ncol_global, &
1188 z_one, aa(1, 1), 1, 1, desca, &
1189 z_zero, cc(1, 1), 1, 1, descc)
1191 cpabort(
"trans only accepts 'T' or 'C'")
1196 DO jj = 1, ncol_global
1197 DO ii = 1, nrow_global
1198 cc(ii, jj) = aa(jj, ii)
1202 DO jj = 1, ncol_global
1203 DO ii = 1, nrow_global
1204 cc(ii, jj) = conjg(aa(jj, ii))
1208 cpabort(
"trans only accepts 'T' or 'C'")
1212 CALL timestop(handle)
1226 TYPE(cp_cfm_type),
INTENT(IN) :: matrix
1227 CHARACTER,
INTENT(IN) :: mode
1228 REAL(kind=
dp) :: res
1230 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_norm'
1232 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: aa
1233 INTEGER :: handle, lwork, ncols, ncols_local, &
1235 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work
1237 #if defined(__SCALAPACK)
1238 INTEGER,
DIMENSION(9) :: desca
1243 CALL timeset(routinen, handle)
1246 nrow_global=nrows, &
1247 ncol_global=ncols, &
1248 nrow_local=nrows_local, &
1249 ncol_local=ncols_local)
1250 aa => matrix%local_data
1255 CASE (
'1',
'O',
'o')
1256 #if defined(__SCALAPACK)
1262 #if defined(__SCALAPACK)
1267 CASE (
'F',
'f',
'E',
'e')
1270 cpabort(
"mode input is not valid")
1273 ALLOCATE (work(lwork))
1275 #if defined(__SCALAPACK)
1276 desca = matrix%matrix_struct%descriptor
1277 res = pzlange(mode, nrows, ncols, aa(1, 1), 1, 1, desca, work)
1280 res = zlange(mode, nrows, ncols, aa(1, 1), lda, work)
1284 CALL timestop(handle)
1297 TYPE(cp_cfm_type),
INTENT(IN) :: matrix
1298 INTEGER,
INTENT(IN) :: irow, jrow
1299 REAL(
dp),
INTENT(IN) :: cs, sn
1301 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_rot_rows'
1302 INTEGER :: handle, nrow, ncol
1303 COMPLEX(KIND=dp) :: sn_cmplx
1305 #if defined(__SCALAPACK)
1306 INTEGER :: info, lwork
1307 INTEGER,
DIMENSION(9) :: desc
1308 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: work
1311 CALL timeset(routinen, handle)
1313 sn_cmplx = cmplx(sn, 0.0_dp,
dp)
1315 #if defined(__SCALAPACK)
1317 ALLOCATE (work(lwork))
1318 desc(:) = matrix%matrix_struct%descriptor(:)
1320 matrix%local_data(1, 1), irow, 1, desc, ncol, &
1321 matrix%local_data(1, 1), jrow, 1, desc, ncol, &
1322 cs, sn_cmplx, work, lwork, info)
1326 CALL zrot(ncol, matrix%local_data(irow, 1), ncol, matrix%local_data(jrow, 1), ncol, cs, sn_cmplx)
1329 CALL timestop(handle)
1342 TYPE(cp_cfm_type),
INTENT(IN) :: matrix
1343 INTEGER,
INTENT(IN) :: icol, jcol
1344 REAL(
dp),
INTENT(IN) :: cs, sn
1346 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_rot_cols'
1347 INTEGER :: handle, nrow, ncol
1348 COMPLEX(KIND=dp) :: sn_cmplx
1350 #if defined(__SCALAPACK)
1351 INTEGER :: info, lwork
1352 INTEGER,
DIMENSION(9) :: desc
1353 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: work
1356 CALL timeset(routinen, handle)
1358 sn_cmplx = cmplx(sn, 0.0_dp,
dp)
1360 #if defined(__SCALAPACK)
1362 ALLOCATE (work(lwork))
1363 desc(:) = matrix%matrix_struct%descriptor(:)
1365 matrix%local_data(1, 1), 1, icol, desc, 1, &
1366 matrix%local_data(1, 1), 1, jcol, desc, 1, &
1367 cs, sn_cmplx, work, lwork, info)
1371 CALL zrot(nrow, matrix%local_data(1, icol), 1, matrix%local_data(1, jcol), 1, cs, sn_cmplx)
1374 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_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_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
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.