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
 
  709      INTEGER                                            :: handle, size_a
 
  711      CALL timeset(routinen, handle)
 
  715      a => matrix_a%local_data
 
  716      size_a = 
SIZE(a, 1)*
SIZE(a, 2)
 
  718      CALL zscal(size_a, alpha, a(1, 1), 1)
 
  720      CALL timestop(handle)
 
 
  721   END SUBROUTINE cp_cfm_zscale
 
  733      TYPE(
cp_cfm_type), 
INTENT(IN)                      :: matrix_a, general_a
 
  734      COMPLEX(kind=dp), 
OPTIONAL                         :: determinant
 
  736      CHARACTER(len=*), 
PARAMETER :: routinen = 
'cp_cfm_solve' 
  738      COMPLEX(kind=dp), 
DIMENSION(:, :), 
POINTER         :: a, a_general
 
  739      INTEGER                                            :: counter, handle, info, irow, nrow_global
 
  740      INTEGER, 
ALLOCATABLE, 
DIMENSION(:)                 :: ipivot
 
  742#if defined(__parallel) 
  743      INTEGER                                            :: icol, ncol_local, nrow_local
 
  744      INTEGER, 
DIMENSION(9)                              :: desca, descb
 
  745      INTEGER, 
DIMENSION(:), 
POINTER                     :: col_indices, row_indices
 
  750      CALL timeset(routinen, handle)
 
  752      a => matrix_a%local_data
 
  753      a_general => general_a%local_data
 
  754      nrow_global = matrix_a%matrix_struct%nrow_global
 
  755      ALLOCATE (ipivot(nrow_global))
 
  757#if defined(__parallel) 
  758      desca(:) = matrix_a%matrix_struct%descriptor(:)
 
  759      descb(:) = general_a%matrix_struct%descriptor(:)
 
  760      CALL pzgetrf(nrow_global, nrow_global, a(1, 1), 1, 1, desca, ipivot, info)
 
  761      IF (
PRESENT(determinant)) 
THEN 
  762         CALL cp_cfm_get_info(matrix_a, nrow_local=nrow_local, ncol_local=ncol_local, &
 
  763                              row_indices=row_indices, col_indices=col_indices)
 
  766         DO irow = 1, nrow_local
 
  767            IF (ipivot(irow) .NE. row_indices(irow)) counter = counter + 1
 
  770         IF (mod(counter, 2) == 0) 
THEN 
  779         DO WHILE (irow <= nrow_local .AND. icol <= ncol_local)
 
  780            IF (row_indices(irow) < col_indices(icol)) 
THEN 
  782            ELSE IF (row_indices(irow) > col_indices(icol)) 
THEN 
  785               determinant = determinant*a(irow, icol)
 
  790         CALL matrix_a%matrix_struct%para_env%prod(determinant)
 
  793      CALL pzgetrs(
"N", nrow_global, nrow_global, a(1, 1), 1, 1, desca, &
 
  794                   ipivot, a_general(1, 1), 1, 1, descb, info)
 
  797      ldb = 
SIZE(a_general, 1)
 
  798      CALL zgetrf(nrow_global, nrow_global, a(1, 1), lda, ipivot, info)
 
  799      IF (
PRESENT(determinant)) 
THEN 
  802         DO irow = 1, nrow_global
 
  803            IF (ipivot(irow) .NE. irow) counter = counter + 1
 
  804            determinant = determinant*a(irow, irow)
 
  806         IF (mod(counter, 2) == 1) determinant = -1.0_dp*determinant
 
  808      CALL zgetrs(
"N", nrow_global, nrow_global, a(1, 1), lda, ipivot, a_general(1, 1), ldb, info)
 
  814      CALL timestop(handle)
 
 
  826      INTEGER, 
INTENT(out), 
OPTIONAL                     :: info_out
 
  828      CHARACTER(len=*), 
PARAMETER :: routinen = 
'cp_cfm_lu_invert' 
  830      COMPLEX(kind=dp), 
ALLOCATABLE, 
DIMENSION(:)        :: work
 
  831      COMPLEX(kind=dp), 
DIMENSION(1)                     :: work1
 
  832      COMPLEX(kind=dp), 
DIMENSION(:, :), 
POINTER         :: mat
 
  833      INTEGER                                            :: handle, info, lwork, nrows_global
 
  834      INTEGER, 
ALLOCATABLE, 
DIMENSION(:)                 :: ipivot
 
  836#if defined(__parallel) 
  838      INTEGER, 
ALLOCATABLE, 
DIMENSION(:)                 :: iwork
 
  839      INTEGER, 
DIMENSION(1)                              :: iwork1
 
  840      INTEGER, 
DIMENSION(9)                              :: desca
 
  845      CALL timeset(routinen, handle)
 
  847      mat => matrix%local_data
 
  848      nrows_global = matrix%matrix_struct%nrow_global
 
  849      cpassert(nrows_global .EQ. matrix%matrix_struct%ncol_global)
 
  850      ALLOCATE (ipivot(nrows_global))
 
  853#if defined(__parallel) 
  854      desca = matrix%matrix_struct%descriptor
 
  855      CALL pzgetrf(nrows_global, nrows_global, &
 
  856                   mat(1, 1), 1, 1, desca, ipivot, info)
 
  859      CALL zgetrf(nrows_global, nrows_global, &
 
  860                  mat(1, 1), lda, ipivot, info)
 
  863         CALL cp_abort(__location__, 
"LU decomposition has failed")
 
  867#if defined(__parallel) 
  868      CALL pzgetri(nrows_global, mat(1, 1), 1, 1, desca, &
 
  869                   ipivot, work1, -1, iwork1, -1, info)
 
  870      lwork = int(work1(1))
 
  871      liwork = int(iwork1(1))
 
  872      ALLOCATE (work(lwork))
 
  873      ALLOCATE (iwork(liwork))
 
  874      CALL pzgetri(nrows_global, mat(1, 1), 1, 1, desca, &
 
  875                   ipivot, work, lwork, iwork, liwork, info)
 
  878      CALL zgetri(nrows_global, mat(1, 1), lda, ipivot, work1, -1, info)
 
  879      lwork = int(work1(1))
 
  880      ALLOCATE (work(lwork))
 
  881      CALL zgetri(nrows_global, mat(1, 1), lda, ipivot, work, lwork, info)
 
  886      IF (
PRESENT(info_out)) 
THEN 
  890            CALL cp_abort(__location__, 
"LU inversion has failed")
 
  893      CALL timestop(handle)
 
 
  910      TYPE(
cp_cfm_type), 
INTENT(IN)                      :: matrix_a, matrix_b
 
  911      COMPLEX(kind=dp), 
INTENT(out)                      :: trace
 
  913      CHARACTER(len=*), 
PARAMETER                        :: routinen = 
'cp_cfm_trace' 
  915      INTEGER                                            :: handle, mypcol, myprow, ncol_local, &
 
  916                                                            npcol, nprow, nrow_local
 
  920      CALL timeset(routinen, handle)
 
  922      context => matrix_a%matrix_struct%context
 
  923      myprow = context%mepos(1)
 
  924      mypcol = context%mepos(2)
 
  925      nprow = context%num_pe(1)
 
  926      npcol = context%num_pe(2)
 
  928      group = matrix_a%matrix_struct%para_env
 
  930      nrow_local = min(matrix_a%matrix_struct%nrow_locals(myprow), matrix_b%matrix_struct%nrow_locals(myprow))
 
  931      ncol_local = min(matrix_a%matrix_struct%ncol_locals(mypcol), matrix_b%matrix_struct%ncol_locals(mypcol))
 
  935                                   matrix_b%local_data(1:nrow_local, 1:ncol_local))
 
  937      CALL group%sum(trace)
 
  939      CALL timestop(handle)
 
 
  978                                         transa_tr, invert_tr, uplo_tr, unit_diag_tr, n_rows, n_cols, &
 
  980      TYPE(
cp_cfm_type), 
INTENT(IN)                      :: triangular_matrix, matrix_b
 
  981      CHARACTER, 
INTENT(in), 
OPTIONAL                    :: side, transa_tr
 
  982      LOGICAL, 
INTENT(in), 
OPTIONAL                      :: invert_tr
 
  983      CHARACTER, 
INTENT(in), 
OPTIONAL                    :: uplo_tr
 
  984      LOGICAL, 
INTENT(in), 
OPTIONAL                      :: unit_diag_tr
 
  985      INTEGER, 
INTENT(in), 
OPTIONAL                      :: n_rows, n_cols
 
  986      COMPLEX(kind=dp), 
INTENT(in), 
OPTIONAL             :: alpha
 
  988      CHARACTER(len=*), 
PARAMETER :: routinen = 
'cp_cfm_triangular_multiply' 
  990      CHARACTER                                          :: side_char, transa, unit_diag, uplo
 
  991      COMPLEX(kind=dp)                                   :: al
 
  992      INTEGER                                            :: handle, m, n
 
  995      CALL timeset(routinen, handle)
 
 1003      IF (
PRESENT(side)) side_char = side
 
 1004      IF (
PRESENT(invert_tr)) invert = invert_tr
 
 1005      IF (
PRESENT(uplo_tr)) uplo = uplo_tr
 
 1006      IF (
PRESENT(unit_diag_tr)) 
THEN 
 1007         IF (unit_diag_tr) 
THEN 
 1013      IF (
PRESENT(transa_tr)) transa = transa_tr
 
 1014      IF (
PRESENT(alpha)) al = alpha
 
 1015      IF (
PRESENT(n_rows)) m = n_rows
 
 1016      IF (
PRESENT(n_cols)) n = n_cols
 
 1020#if defined(__parallel) 
 1021         CALL pztrsm(side_char, uplo, transa, unit_diag, m, n, al, &
 
 1022                     triangular_matrix%local_data(1, 1), 1, 1, &
 
 1023                     triangular_matrix%matrix_struct%descriptor, &
 
 1024                     matrix_b%local_data(1, 1), 1, 1, &
 
 1025                     matrix_b%matrix_struct%descriptor(1))
 
 1027         CALL ztrsm(side_char, uplo, transa, unit_diag, m, n, al, &
 
 1028                    triangular_matrix%local_data(1, 1), &
 
 1029                    SIZE(triangular_matrix%local_data, 1), &
 
 1030                    matrix_b%local_data(1, 1), 
SIZE(matrix_b%local_data, 1))
 
 1035#if defined(__parallel) 
 1036         CALL pztrmm(side_char, uplo, transa, unit_diag, m, n, al, &
 
 1037                     triangular_matrix%local_data(1, 1), 1, 1, &
 
 1038                     triangular_matrix%matrix_struct%descriptor, &
 
 1039                     matrix_b%local_data(1, 1), 1, 1, &
 
 1040                     matrix_b%matrix_struct%descriptor(1))
 
 1042         CALL ztrmm(side_char, uplo, transa, unit_diag, m, n, al, &
 
 1043                    triangular_matrix%local_data(1, 1), &
 
 1044                    SIZE(triangular_matrix%local_data, 1), &
 
 1045                    matrix_b%local_data(1, 1), 
SIZE(matrix_b%local_data, 1))
 
 1050      CALL timestop(handle)
 
 
 1063      CHARACTER, 
INTENT(in), 
OPTIONAL          :: uplo
 
 1064      INTEGER, 
INTENT(out), 
OPTIONAL           :: info_out
 
 1066      CHARACTER(len=*), 
PARAMETER :: routinen = 
'cp_cfm_triangular_invert' 
 1068      CHARACTER                                :: unit_diag, my_uplo
 
 1069      INTEGER                                  :: handle, info, ncol_global
 
 1070      COMPLEX(kind=dp), 
DIMENSION(:, :), &
 
 1072#if defined(__parallel) 
 1073      INTEGER, 
DIMENSION(9)                    :: desca
 
 1076      CALL timeset(routinen, handle)
 
 1080      IF (
PRESENT(uplo)) my_uplo = uplo
 
 1082      ncol_global = matrix_a%matrix_struct%ncol_global
 
 1084      a => matrix_a%local_data
 
 1086#if defined(__parallel) 
 1087      desca(:) = matrix_a%matrix_struct%descriptor(:)
 
 1088      CALL pztrtri(my_uplo, unit_diag, ncol_global, a(1, 1), 1, 1, desca, info)
 
 1090      CALL ztrtri(my_uplo, unit_diag, ncol_global, a(1, 1), ncol_global, info)
 
 1093      IF (
PRESENT(info_out)) 
THEN 
 1097            CALL cp_abort(__location__, &
 
 1098                          "triangular invert failed: matrix is not positive definite  or ill-conditioned")
 
 1101      CALL timestop(handle)
 
 
 1113      CHARACTER, 
INTENT(in)                              :: trans
 
 1116      CHARACTER(len=*), 
PARAMETER :: routinen = 
'cp_cfm_transpose' 
 1118      COMPLEX(kind=dp), 
DIMENSION(:, :), 
POINTER         :: aa, cc
 
 1119      INTEGER                                            :: handle, ncol_global, nrow_global
 
 1120#if defined(__parallel) 
 1121      INTEGER, 
DIMENSION(9)                              :: desca, descc
 
 1122#elif !defined(__MKL) 
 1126      CALL timeset(routinen, handle)
 
 1128      nrow_global = matrix%matrix_struct%nrow_global
 
 1129      ncol_global = matrix%matrix_struct%ncol_global
 
 1131      cpassert(matrixt%matrix_struct%nrow_global == ncol_global)
 
 1132      cpassert(matrixt%matrix_struct%ncol_global == nrow_global)
 
 1134      aa => matrix%local_data
 
 1135      cc => matrixt%local_data
 
 1137#if defined(__parallel) 
 1138      desca = matrix%matrix_struct%descriptor
 
 1139      descc = matrixt%matrix_struct%descriptor
 
 1142         CALL pztranu(nrow_global, ncol_global, &
 
 1143                      z_one, aa(1, 1), 1, 1, desca, &
 
 1144                      z_zero, cc(1, 1), 1, 1, descc)
 
 1146         CALL pztranc(nrow_global, ncol_global, &
 
 1147                      z_one, aa(1, 1), 1, 1, desca, &
 
 1148                      z_zero, cc(1, 1), 1, 1, descc)
 
 1150         cpabort(
"trans only accepts 'T' or 'C'")
 
 1153      CALL mkl_zomatcopy(
'C', trans, nrow_global, ncol_global, 1.0_dp, aa(1, 1), nrow_global, cc(1, 1), ncol_global)
 
 1157         DO jj = 1, ncol_global
 
 1158            DO ii = 1, nrow_global
 
 1159               cc(ii, jj) = aa(jj, ii)
 
 1163         DO jj = 1, ncol_global
 
 1164            DO ii = 1, nrow_global
 
 1165               cc(ii, jj) = conjg(aa(jj, ii))
 
 1169         cpabort(
"trans only accepts 'T' or 'C'")
 
 1173      CALL timestop(handle)
 
 
 1188      CHARACTER, 
INTENT(IN)                              :: mode
 
 1189      REAL(kind=
dp)                                      :: res
 
 1191      CHARACTER(len=*), 
PARAMETER :: routinen = 
'cp_cfm_norm' 
 1193      COMPLEX(kind=dp), 
DIMENSION(:, :), 
POINTER         :: aa
 
 1194      INTEGER                                            :: handle, lwork, ncols, ncols_local, &
 
 1196      REAL(kind=
dp), 
ALLOCATABLE, 
DIMENSION(:)           :: work
 
 1198#if defined(__parallel) 
 1199      INTEGER, 
DIMENSION(9)                              :: desca
 
 1204      CALL timeset(routinen, handle)
 
 1207                           nrow_global=nrows, &
 
 1208                           ncol_global=ncols, &
 
 1209                           nrow_local=nrows_local, &
 
 1210                           ncol_local=ncols_local)
 
 1211      aa => matrix%local_data
 
 1216      CASE (
'1', 
'O', 
'o')
 
 1217#if defined(__parallel) 
 1223#if defined(__parallel) 
 1228      CASE (
'F', 
'f', 
'E', 
'e')
 
 1231         cpabort(
"mode input is not valid")
 
 1234      ALLOCATE (work(lwork))
 
 1236#if defined(__parallel) 
 1237      desca = matrix%matrix_struct%descriptor
 
 1238      res = pzlange(mode, nrows, ncols, aa(1, 1), 1, 1, desca, work)
 
 1241      res = zlange(mode, nrows, ncols, aa(1, 1), lda, work)
 
 1245      CALL timestop(handle)
 
 
 1259      INTEGER, 
INTENT(IN)                      :: irow, jrow
 
 1260      REAL(
dp), 
INTENT(IN)                     :: cs, sn
 
 1262      CHARACTER(len=*), 
PARAMETER :: routinen = 
'cp_cfm_rot_rows' 
 1263      INTEGER                                  :: handle, ncol
 
 1264      COMPLEX(KIND=dp)                         :: sn_cmplx
 
 1266#if defined(__parallel) 
 1267      INTEGER                                  :: info, lwork
 
 1268      INTEGER, 
DIMENSION(9)                    :: desc
 
 1269      REAL(
dp), 
DIMENSION(:), 
ALLOCATABLE      :: work
 
 1271      CALL timeset(routinen, handle)
 
 1273      sn_cmplx = cmplx(sn, 0.0_dp, 
dp)
 
 1274#if defined(__parallel) 
 1275      IF (1 /= matrix%matrix_struct%context%n_pid) 
THEN 
 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)
 
 1287         CALL zrot(ncol, matrix%local_data(irow, 1), ncol, matrix%local_data(jrow, 1), ncol, cs, sn_cmplx)
 
 1288#if defined(__parallel) 
 1291      CALL timestop(handle)
 
 
 1305      INTEGER, 
INTENT(IN)                      :: icol, jcol
 
 1306      REAL(
dp), 
INTENT(IN)                     :: cs, sn
 
 1308      CHARACTER(len=*), 
PARAMETER :: routinen = 
'cp_cfm_rot_cols' 
 1309      INTEGER                                  :: handle, nrow
 
 1310      COMPLEX(KIND=dp)                         :: sn_cmplx
 
 1312#if defined(__parallel) 
 1313      INTEGER                                  :: info, lwork
 
 1314      INTEGER, 
DIMENSION(9)                    :: desc
 
 1315      REAL(
dp), 
DIMENSION(:), 
ALLOCATABLE      :: work
 
 1317      CALL timeset(routinen, handle)
 
 1319      sn_cmplx = cmplx(sn, 0.0_dp, 
dp)
 
 1320#if defined(__parallel) 
 1321      IF (1 /= matrix%matrix_struct%context%n_pid) 
THEN 
 1323         ALLOCATE (work(lwork))
 
 1324         desc(:) = matrix%matrix_struct%descriptor(:)
 
 1326                    matrix%local_data(1, 1), 1, icol, desc, 1, &
 
 1327                    matrix%local_data(1, 1), 1, jcol, desc, 1, &
 
 1328                    cs, sn_cmplx, work, lwork, info)
 
 1333         CALL zrot(nrow, matrix%local_data(1, icol), 1, matrix%local_data(1, jcol), 1, cs, sn_cmplx)
 
 1334#if defined(__parallel) 
 1337      CALL timestop(handle)
 
 
 1352      TYPE(
cp_cfm_type), 
INTENT(IN), 
OPTIONAL            :: workspace
 
 1353      CHARACTER, 
INTENT(IN), 
OPTIONAL                    :: uplo
 
 1355      CHARACTER(LEN=*), 
PARAMETER :: routinen = 
'cp_cfm_uplo_to_full' 
 1358      INTEGER                                            :: handle, i_global, iib, j_global, jjb, &
 
 1359                                                            ncol_local, nrow_local
 
 1360      INTEGER, 
DIMENSION(:), 
POINTER                     :: col_indices, row_indices
 
 1363      CALL timeset(routinen, handle)
 
 1365      IF (.NOT. 
PRESENT(workspace)) 
THEN 
 1372      IF (
PRESENT(uplo)) myuplo = uplo
 
 1376                           nrow_local=nrow_local, &
 
 1377                           ncol_local=ncol_local, &
 
 1378                           row_indices=row_indices, &
 
 1379                           col_indices=col_indices)
 
 1381      DO jjb = 1, ncol_local
 
 1382         j_global = col_indices(jjb)
 
 1383         DO iib = 1, nrow_local
 
 1384            i_global = row_indices(iib)
 
 1385            IF (merge(j_global < i_global, j_global > i_global, (myuplo == 
"U") .OR. (myuplo == 
"u"))) 
THEN 
 1386               matrix%local_data(iib, jjb) = 
z_zero 
 1387            ELSE IF (j_global == i_global) 
THEN 
 1388               matrix%local_data(iib, jjb) = matrix%local_data(iib, jjb)/(2.0_dp, 0.0_dp)
 
 1397      IF (.NOT. 
PRESENT(workspace)) 
THEN 
 1401      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.