filter a dbcsr matrix
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(dbcsr_type), | intent(inout) | :: | matrix |
the matrix |
||
type(dbcsr_scalar_type), | intent(in) | :: | eps |
the threshold |
||
integer, | intent(in), | optional | :: | method |
how the matrix is filtered |
|
logical, | intent(in), | optional | :: | use_absolute |
NYI |
|
logical, | intent(in), | optional | :: | filter_diag |
NYI |
SUBROUTINE dbcsr_filter_anytype(matrix, eps, method, &
use_absolute, filter_diag)
!! filter a dbcsr matrix
TYPE(dbcsr_type), INTENT(INOUT) :: matrix
!! the matrix
TYPE(dbcsr_scalar_type), INTENT(IN) :: eps
!! the threshold
INTEGER, INTENT(IN), OPTIONAL :: method
!! how the matrix is filtered
LOGICAL, INTENT(in), OPTIONAL :: use_absolute, filter_diag
!! NYI
CHARACTER(len=*), PARAMETER :: routineN = 'dbcsr_filter_anytype'
COMPLEX(KIND=real_4), DIMENSION(:), POINTER :: data_c
COMPLEX(KIND=real_8), DIMENSION(:), POINTER :: data_z
INTEGER :: blk, blk_nze, col, col_size, handle, &
my_method, row, row_size, data_type
LOGICAL :: gt0, my_filter_diag, tr
REAL(KIND=real_4) :: nrm_s
REAL(KIND=real_4), DIMENSION(:), POINTER :: data_s
REAL(KIND=real_8) :: my_absolute, nrm_d
REAL(KIND=real_8), DIMENSION(:), POINTER :: data_d
TYPE(dbcsr_iterator) :: iter
REAL(KIND=real_8), EXTERNAL :: DZNRM2
#if defined (__ACCELERATE)
REAL(KIND=real_8), EXTERNAL :: SCNRM2
#else
REAL(KIND=real_4), EXTERNAL :: SCNRM2
#endif
! ---------------------------------------------------------------------------
CALL timeset(routineN, handle)
my_method = dbcsr_filter_frobenius
IF (PRESENT(method)) my_method = method
my_absolute = 1.0_dp
IF (PRESENT(use_absolute)) my_absolute = dbcsr_maxabs(matrix)
my_filter_diag = .TRUE.
IF (PRESENT(filter_diag)) my_filter_diag = filter_diag
SELECT CASE (eps%data_type)
CASE (dbcsr_type_real_4)
gt0 = eps%r_sp .GT. 0.0_real_4
CASE (dbcsr_type_real_8)
gt0 = eps%r_dp .GT. 0.0_real_8
CASE (dbcsr_type_complex_4)
gt0 = ABS(eps%c_sp) .GT. 0.0_real_4
CASE (dbcsr_type_complex_8)
gt0 = ABS(eps%c_dp) .GT. 0.0_real_8
CASE default
gt0 = .FALSE.
END SELECT
IF (gt0) THEN
data_type = dbcsr_get_data_type(matrix)
!$OMP PARALLEL DEFAULT(NONE) PRIVATE(iter,row,col,data_s,data_d,data_c,data_z,tr, &
!$OMP blk,row_size,col_size,blk_nze,nrm_d,nrm_s) &
!$OMP SHARED(my_method,my_absolute,eps,matrix,data_type)
CALL dbcsr_iterator_start(iter, matrix, contiguous_pointers=.TRUE.)
DO WHILE (dbcsr_iterator_blocks_left(iter))
SELECT CASE (data_type)
CASE (dbcsr_type_real_4)
CALL dbcsr_iterator_next_block(iter, row, col, data_s, tr, blk, &
row_size, col_size)
blk_nze = row_size*col_size
IF (blk_nze .EQ. 0) CYCLE ! Skip empty blocks
SELECT CASE (my_method)
CASE (dbcsr_filter_frobenius)
!
! Frobenius based
nrm_s = norm2(data_s)
IF (nrm_s .LT. my_absolute*eps%r_sp) &
CALL dbcsr_remove_block(matrix, row, col, blk_nze, blk)
CASE DEFAULT
DBCSR_ABORT("Only Frobenius based filtering")
END SELECT
CASE (dbcsr_type_real_8)
CALL dbcsr_iterator_next_block(iter, row, col, data_d, tr, blk, &
row_size, col_size)
blk_nze = row_size*col_size
IF (blk_nze .EQ. 0) CYCLE ! Skip empty blocks
SELECT CASE (my_method)
CASE (dbcsr_filter_frobenius)
!
! Frobenius based
nrm_d = norm2(data_d)
IF (nrm_d .LT. my_absolute*eps%r_dp) &
CALL dbcsr_remove_block(matrix, row, col, blk_nze, blk)
CASE DEFAULT
DBCSR_ABORT("Only Frobenius based filtering")
END SELECT
CASE (dbcsr_type_complex_4)
CALL dbcsr_iterator_next_block(iter, row, col, data_c, tr, blk, &
row_size, col_size)
blk_nze = row_size*col_size
IF (blk_nze .EQ. 0) CYCLE ! Skip empty blocks
SELECT CASE (my_method)
CASE (dbcsr_filter_frobenius)
!
! Frobenius based
nrm_d = SCNRM2(SIZE(data_c), data_c(1), 1)
IF (nrm_d .LT. my_absolute*eps%r_dp) &
CALL dbcsr_remove_block(matrix, row, col, blk_nze, blk)
CASE DEFAULT
DBCSR_ABORT("Only Frobenius based filtering")
END SELECT
CASE (dbcsr_type_complex_8)
CALL dbcsr_iterator_next_block(iter, row, col, data_z, tr, blk, &
row_size, col_size)
blk_nze = row_size*col_size
IF (blk_nze .EQ. 0) CYCLE ! Skip empty blocks
SELECT CASE (my_method)
CASE (dbcsr_filter_frobenius)
!
! Frobenius based
nrm_d = DZNRM2(SIZE(data_z), data_z(1), 1)
IF (nrm_d .LT. my_absolute*eps%r_dp) &
CALL dbcsr_remove_block(matrix, row, col, blk_nze, blk)
CASE DEFAULT
DBCSR_ABORT("Only Frobenius based filtering")
END SELECT
CASE DEFAULT
DBCSR_ABORT("Wrong data type")
END SELECT
END DO
CALL dbcsr_iterator_stop(iter)
CALL dbcsr_finalize(matrix, reshuffle=.TRUE.)
!$OMP END PARALLEL
CALL dbcsr_index_compact(matrix)
END IF
CALL timestop(handle)
END SUBROUTINE dbcsr_filter_anytype