42 #include "./base/base_uses.f90"
48 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'matrix_exp'
69 TYPE(cp_fm_type),
DIMENSION(2) :: exp_h
70 TYPE(cp_fm_type),
INTENT(IN) :: im_matrix
71 INTEGER,
INTENT(in) :: nsquare, ntaylor
73 CHARACTER(len=*),
PARAMETER :: routinen =
'taylor_only_imaginary'
74 REAL(kind=
dp),
PARAMETER :: one = 1.0_dp, zero = 0.0_dp
76 INTEGER :: handle, i, ndim, nloop
77 REAL(kind=
dp) :: square_fac, tfac, tmp
78 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
79 POINTER :: local_data_im
80 TYPE(cp_fm_type) :: t1, t2, tres_im, tres_re
82 CALL timeset(routinen, handle)
85 ndim = im_matrix%matrix_struct%nrow_global
87 square_fac = 1.0_dp/(2.0_dp**real(nsquare,
dp))
90 matrix_struct=im_matrix%matrix_struct, &
94 matrix_struct=t1%matrix_struct, &
97 matrix_struct=t1%matrix_struct, &
100 matrix_struct=t1%matrix_struct, &
109 nloop = ceiling(real(ntaylor,
dp)/2.0_dp)
112 tmp = tmp*(real(i,
dp)*2.0_dp - 1.0_dp)
113 CALL parallel_gemm(
"N",
"N", ndim, ndim, ndim, square_fac, im_matrix, t1, zero, &
117 IF (mod(i, 2) == 0) tfac = -tfac
119 tmp = tmp*real(i,
dp)*2.0_dp
120 CALL parallel_gemm(
"N",
"N", ndim, ndim, ndim, square_fac, im_matrix, t2, zero, &
124 IF (mod(i, 2) == 1) tfac = -tfac
129 IF (nsquare .GT. 0)
THEN
132 tres_re, tres_im, zero, exp_h(1), exp_h(2))
134 CALL cp_fm_to_fm(exp_h(1), tres_re)
135 CALL cp_fm_to_fm(exp_h(2), tres_im)
138 CALL cp_fm_to_fm(tres_re, exp_h(1))
139 CALL cp_fm_to_fm(tres_im, exp_h(2))
142 CALL cp_fm_release(t1)
143 CALL cp_fm_release(t2)
144 CALL cp_fm_release(tres_re)
145 CALL cp_fm_release(tres_im)
147 CALL timestop(handle)
165 TYPE(cp_fm_type),
DIMENSION(2) :: exp_h
166 TYPE(cp_fm_type),
INTENT(IN) :: re_part, im_part
167 INTEGER,
INTENT(in) :: nsquare, ntaylor
169 CHARACTER(len=*),
PARAMETER :: routinen =
'taylor_full_complex'
171 COMPLEX(KIND=dp) :: tfac
172 INTEGER :: handle, i, ndim
173 REAL(kind=
dp) :: square_fac, tmp
174 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
175 POINTER :: local_data_im, local_data_re
176 TYPE(cp_cfm_type) :: t1, t2, t3, tres
178 CALL timeset(routinen, handle)
181 ndim = re_part%matrix_struct%nrow_global
184 matrix_struct=re_part%matrix_struct, &
187 square_fac = 2.0_dp**real(nsquare,
dp)
189 t1%local_data = cmplx(local_data_re/square_fac, local_data_im/square_fac, kind=
dp)
192 matrix_struct=t1%matrix_struct, &
195 matrix_struct=t1%matrix_struct, &
198 matrix_struct=t1%matrix_struct, &
206 tmp = tmp*real(i,
dp)
207 CALL parallel_gemm(
"N",
"N", ndim, ndim, ndim,
z_one, t1, t2,
z_zero, &
209 tfac = cmplx(1._dp/tmp, 0.0_dp, kind=
dp)
211 CALL cp_cfm_to_cfm(t3, t2)
214 IF (nsquare .GT. 0)
THEN
216 CALL parallel_gemm(
"N",
"N", ndim, ndim, ndim,
z_one, tres, tres,
z_zero, &
218 CALL cp_cfm_to_cfm(t2, tres)
222 exp_h(1)%local_data = real(tres%local_data, kind=
dp)
223 exp_h(2)%local_data = aimag(tres%local_data)
229 CALL timestop(handle)
245 REAL(
dp),
INTENT(in) :: norm
246 INTEGER,
INTENT(out) :: nsquare, norder
247 REAL(
dp),
INTENT(in) :: eps_exp
248 INTEGER,
INTENT(in) :: method
249 LOGICAL,
INTENT(in) :: do_emd
251 INTEGER :: cost, i, iscale, orders(3), p, &
254 REAL(
dp) :: d, eval, myval, n, scaled, scalen
256 orders(:) = (/12, 12, 12/)
257 IF (method == 2)
THEN
260 eval = norm/(2.0_dp**real(iscale,
dp))
262 DO p = max(1, q - 1), q
267 IF (i .LE. p) scalen =
fac(p + q - i)*
fac(p)/(
fac(p + q)*
fac(i)*
fac(p - i))
268 scaled = (-1.0)**i*
fac(p + q - i)*
fac(q)/(
fac(p + q)*
fac(i)*
fac(q - i))
269 IF (i .LE. p) n = n + scalen*eval**i
270 d = d + scaled*eval**i
272 IF (abs((exp(norm) - (n/d)**(2.0_dp**iscale))/max(1.0_dp, exp(norm))) .LE. eps_exp)
THEN
275 prev_cost = orders(1) + orders(2)
277 cost = iscale + ceiling(real(q,
dp)/3.0_dp)
278 prev_cost = orders(1) + ceiling(real(orders(2),
dp)/3.0_dp)
280 IF (cost .LT. prev_cost)
THEN
281 orders(:) = (/iscale, q, p/)
282 myval = (n/d)**(2.0_dp**iscale)
290 IF (iscale .GE. orders(1) + orders(2) .AND. new_scale)
EXIT
292 ELSE IF (method == 1)
THEN
297 IF (iscale .GE. 1) eval = norm/(2.0_dp**real(iscale,
dp))
302 scalen = 1.0_dp/
fac(i)
303 n = n + scalen*(eval**real(i,
dp))
305 IF (abs((exp(norm) - n**(2.0_dp**real(iscale,
dp)))/max(1.0_dp, exp(norm))) .LE. eps_exp)
THEN
308 prev_cost = orders(1) + orders(2)
310 cost = iscale + ceiling(real(p,
dp)/3.0_dp)
311 prev_cost = orders(1) + ceiling(real(orders(2),
dp)/3.0_dp)
313 IF (cost .LT. prev_cost)
THEN
314 orders(:) = (/iscale, p, 0/)
315 myval = (n)**(2.0_dp**iscale)
321 IF (iscale .GE. orders(1) + orders(2) .AND. new_scale)
EXIT
342 TYPE(cp_fm_type),
DIMENSION(2) :: exp_h
343 TYPE(cp_fm_type),
INTENT(IN) :: re_part, im_part
344 INTEGER,
INTENT(in) :: nsquare, npade
346 CHARACTER(len=*),
PARAMETER :: routinen =
'exp_pade_full_complex'
348 COMPLEX(KIND=dp) :: scaled, scalen
349 INTEGER :: handle, i, ldim, ndim, p, q
350 REAL(kind=
dp) :: square_fac, tmp
351 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
352 POINTER :: local_data_im, local_data_re
353 TYPE(cp_cfm_type) :: dpq, fin_p, t1
354 TYPE(cp_cfm_type),
DIMENSION(2) :: mult_p
355 TYPE(cp_cfm_type),
TARGET :: npq, t2, tres
360 CALL timeset(routinen, handle)
361 CALL cp_fm_get_info(re_part, local_data=local_data_re, ncol_local=ldim, &
366 matrix_struct=re_part%matrix_struct, &
369 square_fac = 2.0_dp**real(nsquare,
dp)
372 matrix_struct=dpq%matrix_struct, &
376 matrix_struct=t1%matrix_struct, &
379 matrix_struct=t1%matrix_struct, &
382 matrix_struct=t1%matrix_struct, &
386 t2%local_data(:, i) = cmplx(local_data_re(:, i)/square_fac, local_data_im(:, i)/square_fac, kind=
dp)
388 CALL cp_cfm_to_cfm(t2, t1)
398 IF (npade .GT. 2)
THEN
400 IF (i .LE. p) scalen = cmplx(
fac(p + q - i)*
fac(p)/(
fac(p + q)*
fac(i)*
fac(p - i)), 0.0_dp, kind=
dp)
401 scaled = cmplx((-1.0_dp)**i*
fac(p + q - i)*
fac(q)/(
fac(p + q)*
fac(i)*
fac(q - i)), 0.0_dp, kind=
dp)
402 CALL parallel_gemm(
"N",
"N", ndim, ndim, ndim,
z_one, t1, mult_p(mod(i, 2) + 1),
z_zero, &
403 mult_p(mod(i + 1, 2) + 1))
413 IF (nsquare .GT. 0)
THEN
415 CALL parallel_gemm(
"N",
"N", ndim, ndim, ndim,
z_one, mult_p(mod(i, 2) + 1), mult_p(mod(i, 2) + 1),
z_zero, &
416 mult_p(mod(i + 1, 2) + 1))
417 fin_p = mult_p(mod(i + 1, 2) + 1)
423 exp_h(1)%local_data(:, i) = real(fin_p%local_data(:, i), kind=
dp)
424 exp_h(2)%local_data(:, i) = aimag(fin_p%local_data(:, i))
432 CALL timestop(handle)
447 TYPE(cp_fm_type),
DIMENSION(2) :: exp_h
448 TYPE(cp_fm_type),
INTENT(IN) :: im_part
449 INTEGER,
INTENT(in) :: nsquare, npade
451 CHARACTER(len=*),
PARAMETER :: routinen =
'exp_pade_only_imaginary'
452 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
454 COMPLEX(KIND=dp) :: scaled, scalen
455 INTEGER :: handle, i, j, k, ldim, ndim, p, q
456 REAL(kind=
dp) :: my_fac, square_fac
457 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
458 POINTER :: local_data_im
459 TYPE(cp_cfm_type) :: dpq, fin_p
460 TYPE(cp_cfm_type),
DIMENSION(2) :: cmult_p
461 TYPE(cp_cfm_type),
TARGET :: npq, t1
462 TYPE(cp_fm_type) :: t2, tres
464 CALL timeset(routinen, handle)
468 CALL cp_fm_get_info(im_part, local_data=local_data_im, ncol_local=ldim, nrow_global=ndim)
469 square_fac = 1.0_dp/(2.0_dp**real(nsquare,
dp))
472 matrix_struct=im_part%matrix_struct, &
476 matrix_struct=dpq%matrix_struct, &
480 matrix_struct=dpq%matrix_struct, &
484 matrix_struct=t1%matrix_struct, &
488 matrix_struct=t1%matrix_struct, &
495 CALL cp_fm_to_fm(im_part, t2)
501 npq%local_data(:, i) = npq%local_data(:, i) + cmplx(rzero, 0.5_dp*square_fac*local_data_im(:, i),
dp)
502 dpq%local_data(:, i) = dpq%local_data(:, i) - cmplx(rzero, 0.5_dp*square_fac*local_data_im(:, i),
dp)
505 IF (npade .GT. 2)
THEN
506 DO j = 1, floor(npade/2.0_dp)
509 IF (i .LE. p) scalen = cmplx(my_fac*
fac(p + q - i)*
fac(p)/(
fac(p + q)*
fac(i)*
fac(p - i)), 0.0_dp,
dp)
510 scaled = cmplx(my_fac*
fac(p + q - i)*
fac(q)/(
fac(p + q)*
fac(i)*
fac(q - i)), 0.0_dp,
dp)
511 CALL parallel_gemm(
"N",
"N", ndim, ndim, ndim, square_fac, im_part, t2, rzero, tres)
514 npq%local_data(:, k) = npq%local_data(:, k) + scalen*tres%local_data(:, k)
515 dpq%local_data(:, k) = dpq%local_data(:, k) + scaled*tres%local_data(:, k)
518 IF (2*j + 1 .LE. q)
THEN
520 IF (i .LE. p) scalen = cmplx(my_fac*
fac(p + q - i)*
fac(p)/(
fac(p + q)*
fac(i)*
fac(p - i)), rzero,
dp)
521 scaled = cmplx(-my_fac*
fac(p + q - i)*
fac(q)/(
fac(p + q)*
fac(i)*
fac(q - i)), rzero,
dp)
522 CALL parallel_gemm(
"N",
"N", ndim, ndim, ndim, square_fac, im_part, tres, rzero, t2)
525 npq%local_data(:, k) = npq%local_data(:, k) + scalen*cmplx(rzero, t2%local_data(:, k),
dp)
526 dpq%local_data(:, k) = dpq%local_data(:, k) + scaled*cmplx(rzero, t2%local_data(:, k),
dp)
536 IF (nsquare .GT. 0)
THEN
538 CALL parallel_gemm(
"N",
"N", ndim, ndim, ndim,
z_one, cmult_p(mod(i, 2) + 1), cmult_p(mod(i, 2) + 1),
z_zero, &
539 cmult_p(mod(i + 1, 2) + 1))
540 fin_p = cmult_p(mod(i + 1, 2) + 1)
547 exp_h(1)%local_data(:, k) = real(fin_p%local_data(:, k), kind=
dp)
548 exp_h(2)%local_data(:, k) = aimag(fin_p%local_data(:, k))
554 CALL cp_fm_release(t2)
555 CALL cp_fm_release(tres)
556 CALL timestop(handle)
570 TYPE(cp_fm_type),
INTENT(IN) :: exp_h, matrix
571 INTEGER,
INTENT(in) :: nsquare, npade
573 CHARACTER(len=*),
PARAMETER :: routinen =
'exp_pade_real'
574 REAL(kind=
dp),
PARAMETER :: one = 1.0_dp, zero = 0.0_dp
576 INTEGER :: handle, i, j, k, ldim, ndim, p, q
577 REAL(kind=
dp) :: my_fac, scaled, scalen, square_fac
578 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
579 POINTER :: local_data
580 TYPE(cp_fm_type) :: dpq, fin_p
581 TYPE(cp_fm_type),
DIMENSION(2) :: mult_p
582 TYPE(cp_fm_type),
TARGET :: npq, t1, t2, tres
584 CALL timeset(routinen, handle)
588 CALL cp_fm_get_info(matrix, local_data=local_data, ncol_local=ldim, nrow_global=ndim)
589 square_fac = 2.0_dp**real(nsquare,
dp)
592 matrix_struct=matrix%matrix_struct, &
596 matrix_struct=dpq%matrix_struct, &
600 matrix_struct=dpq%matrix_struct, &
604 matrix_struct=t1%matrix_struct, &
608 matrix_struct=t1%matrix_struct, &
612 t2%local_data(:, i) = local_data(:, i)/square_fac
615 CALL cp_fm_to_fm(t2, t1)
620 npq%local_data(:, i) = npq%local_data(:, i) + 0.5_dp*local_data(:, i)
621 dpq%local_data(:, i) = dpq%local_data(:, i) - 0.5_dp*local_data(:, i)
627 IF (npade .GE. 2)
THEN
629 my_fac = (-1.0_dp)**j
632 CALL parallel_gemm(
"N",
"N", ndim, ndim, ndim, one, mult_p(mod(j, 2) + 1), t1, &
633 zero, mult_p(mod(j + 1, 2) + 1))
636 npq%local_data(:, k) = npq%local_data(:, k) + scalen*mult_p(mod(j + 1, 2) + 1)%local_data(:, k)
637 dpq%local_data(:, k) = dpq%local_data(:, k) + scaled*mult_p(mod(j + 1, 2) + 1)%local_data(:, k)
646 IF (nsquare .GT. 0)
THEN
648 CALL parallel_gemm(
"N",
"N", ndim, ndim, ndim, one, mult_p(mod(i, 2) + 1), mult_p(mod(i, 2) + 1), zero, &
649 mult_p(mod(i + 1, 2) + 1))
651 fin_p = mult_p(mod(nsquare + 1, 2) + 1)
657 exp_h%local_data(:, k) = fin_p%local_data(:, k)
660 CALL cp_fm_release(npq)
661 CALL cp_fm_release(dpq)
662 CALL cp_fm_release(t1)
663 CALL cp_fm_release(t2)
664 CALL cp_fm_release(tres)
665 CALL timestop(handle)
682 SUBROUTINE arnoldi(mos_old, mos_new, eps_exp, Hre, Him, mos_next, narn_old)
684 TYPE(cp_fm_type),
DIMENSION(2) :: mos_old, mos_new
685 REAL(kind=
dp),
INTENT(in) :: eps_exp
686 TYPE(cp_fm_type),
INTENT(IN),
OPTIONAL :: hre
687 TYPE(cp_fm_type),
INTENT(IN) :: him
688 TYPE(cp_fm_type),
DIMENSION(2),
OPTIONAL :: mos_next
689 INTEGER,
INTENT(inout) :: narn_old
691 CHARACTER(len=*),
PARAMETER :: routinen =
'arnoldi'
692 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
694 INTEGER :: handle, i, icol_local, idim, info, j, l, &
695 mydim, nao, narnoldi, ncol_local, &
696 newdim, nmo, npade, pade_step
697 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipivot
698 INTEGER,
DIMENSION(:),
POINTER :: col_indices, col_procs
699 LOGICAL :: convergence, double_col, double_row
700 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: last_norm, norm1, results
701 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: d, mat1, mat2, mat3, n
702 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: h_approx, h_approx_save
703 REAL(kind=
dp) :: conv_norm, prefac, scaled, scalen
704 TYPE(cp_fm_struct_type),
POINTER :: mo_struct, newstruct
705 TYPE(cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: v_mats
706 TYPE(mp_comm_type) :: col_group
707 TYPE(mp_para_env_type),
POINTER :: para_env
709 CALL timeset(routinen, handle)
710 para_env => mos_new(1)%matrix_struct%para_env
712 CALL cp_fm_get_info(mos_old(1), ncol_local=ncol_local, col_indices=col_indices, &
713 nrow_global=nao, ncol_global=nmo, matrix_struct=mo_struct)
714 narnoldi = min(18, nao)
716 ALLOCATE (results(ncol_local))
717 ALLOCATE (norm1(ncol_local))
718 ALLOCATE (v_mats(narnoldi + 1))
719 ALLOCATE (last_norm(ncol_local))
720 ALLOCATE (h_approx(narnoldi, narnoldi, ncol_local))
721 ALLOCATE (h_approx_save(narnoldi, narnoldi, ncol_local))
722 col_procs => mo_struct%context%blacs2mpi(:, mo_struct%context%mepos(2))
723 CALL col_group%from_reordering(para_env, col_procs)
728 h_approx_save = rzero
730 DO i = 1, narnoldi + 1
732 name=
"V_mat"//cp_to_string(i))
738 DO icol_local = 1, ncol_local
739 v_mats(1)%local_data(:, icol_local) = mos_old(1)%local_data(:, icol_local)
740 v_mats(1)%local_data(:, icol_local + ncol_local) = mos_old(2)%local_data(:, icol_local)
741 norm1(icol_local) = sum(v_mats(1)%local_data(:, icol_local)**2) &
742 + sum(v_mats(1)%local_data(:, icol_local + ncol_local)**2)
745 CALL col_group%sum(norm1)
747 norm1(:) = sqrt(norm1(:))
750 DO icol_local = 1, ncol_local
751 v_mats(1)%local_data(:, icol_local) = v_mats(1)%local_data(:, icol_local)/norm1(icol_local)
752 v_mats(1)%local_data(:, icol_local + ncol_local) = &
753 v_mats(1)%local_data(:, icol_local + ncol_local)/norm1(icol_local)
757 DO i = 2, narnoldi + 1
759 CALL parallel_gemm(
"N",
"N", nao, newdim, nao, 1.0_dp, him, v_mats(i - 1), 0.0_dp, v_mats(i))
762 DO icol_local = 1, ncol_local
763 mos_new(1)%local_data(:, icol_local) = v_mats(i)%local_data(:, icol_local)
764 v_mats(i)%local_data(:, icol_local) = -v_mats(i)%local_data(:, icol_local + ncol_local)
765 v_mats(i)%local_data(:, icol_local + ncol_local) = mos_new(1)%local_data(:, icol_local)
768 IF (
PRESENT(hre))
THEN
769 CALL parallel_gemm(
"N",
"N", nao, newdim, nao, 1.0_dp, hre, v_mats(i - 1), 1.0_dp, v_mats(i))
774 DO icol_local = 1, ncol_local
775 results(icol_local) = sum(v_mats(l)%local_data(:, icol_local)*v_mats(i)%local_data(:, icol_local)) + &
776 sum(v_mats(l)%local_data(:, icol_local + ncol_local)* &
777 v_mats(i)%local_data(:, icol_local + ncol_local))
780 CALL col_group%sum(results)
783 DO icol_local = 1, ncol_local
784 h_approx_save(l, i - 1, icol_local) = results(icol_local)
785 v_mats(i)%local_data(:, icol_local) = v_mats(i)%local_data(:, icol_local) - &
786 results(icol_local)*v_mats(l)%local_data(:, icol_local)
787 v_mats(i)%local_data(:, icol_local + ncol_local) = &
788 v_mats(i)%local_data(:, icol_local + ncol_local) - &
789 results(icol_local)*v_mats(l)%local_data(:, icol_local + ncol_local)
794 DO icol_local = 1, ncol_local
795 results(icol_local) = sum(v_mats(i)%local_data(:, icol_local)**2) + &
796 sum(v_mats(i)%local_data(:, icol_local + ncol_local)**2)
799 CALL col_group%sum(results)
801 IF (i .LE. narnoldi)
THEN
804 DO icol_local = 1, ncol_local
805 h_approx_save(i, i - 1, icol_local) = sqrt(results(icol_local))
806 last_norm(icol_local) = sqrt(results(icol_local))
807 v_mats(i)%local_data(:, icol_local) = v_mats(i)%local_data(:, icol_local)/sqrt(results(icol_local))
808 v_mats(i)%local_data(:, icol_local + ncol_local) = &
809 v_mats(i)%local_data(:, icol_local + ncol_local)/sqrt(results(icol_local))
813 DO icol_local = 1, ncol_local
814 last_norm(icol_local) = sqrt(results(icol_local))
818 h_approx(:, :, :) = h_approx_save
822 convergence = .false.
823 IF (i .GE. narn_old)
THEN
825 mydim = min(i, narnoldi)
826 ALLOCATE (ipivot(mydim))
827 ALLOCATE (mat1(mydim, mydim))
828 ALLOCATE (mat2(mydim, mydim))
829 ALLOCATE (mat3(mydim, mydim))
830 ALLOCATE (n(mydim, mydim))
831 ALLOCATE (d(mydim, mydim))
832 DO icol_local = 1, ncol_local
835 mat1(idim, j) = h_approx(idim, j, icol_local)/16.0_dp
836 mat3(idim, j) = mat1(idim, j)
845 n(:, :) = n + 0.5_dp*mat1
846 d(:, :) = d - 0.5_dp*mat1
849 pade_step = pade_step + 1
850 CALL dgemm(
"N",
'N', mydim, mydim, mydim, rone, mat1(1, 1), &
851 mydim, mat3(1, 1), mydim, rzero, mat2(1, 1), mydim)
852 scalen = real(
fac(2*npade - pade_step)*
fac(npade)/ &
853 (
fac(2*npade)*
fac(pade_step)*
fac(npade - pade_step)),
dp)
854 scaled = real((-1.0_dp)**pade_step*
fac(2*npade - pade_step)*
fac(npade)/ &
855 (
fac(2*npade)*
fac(pade_step)*
fac(npade - pade_step)),
dp)
856 n(:, :) = n + scalen*mat2
857 d(:, :) = d + scaled*mat2
858 pade_step = pade_step + 1
859 CALL dgemm(
"N",
'N', mydim, mydim, mydim, rone, mat2(1, 1), &
860 mydim, mat1(1, 1), mydim, rzero, mat3(1, 1), mydim)
861 scalen = real(
fac(2*npade - pade_step)*
fac(npade)/ &
862 (
fac(2*npade)*
fac(pade_step)*
fac(npade - pade_step)),
dp)
863 scaled = real((-1.0_dp)**pade_step*
fac(2*npade - pade_step)*
fac(npade)/ &
864 (
fac(2*npade)*
fac(pade_step)*
fac(npade - pade_step)),
dp)
865 n(:, :) = n + scalen*mat3
866 d(:, :) = d + scaled*mat3
869 CALL dgetrf(mydim, mydim, d(1, 1), mydim, ipivot, info)
870 CALL dgetrs(
"N", mydim, mydim, d(1, 1), mydim, ipivot, n, mydim, info)
871 CALL dgemm(
"N",
'N', mydim, mydim, mydim, rone, n(1, 1), mydim, n(1, 1), mydim, rzero, mat1(1, 1), mydim)
872 CALL dgemm(
"N",
'N', mydim, mydim, mydim, rone, mat1(1, 1), mydim, mat1(1, 1), mydim, rzero, n(1, 1), mydim)
873 CALL dgemm(
"N",
'N', mydim, mydim, mydim, rone, n(1, 1), mydim, n(1, 1), mydim, rzero, mat1(1, 1), mydim)
874 CALL dgemm(
"N",
'N', mydim, mydim, mydim, rone, mat1(1, 1), mydim, mat1(1, 1), mydim, rzero, n(1, 1), mydim)
877 h_approx(idim, j, icol_local) = n(idim, j)
884 DO icol_local = 1, ncol_local
885 results(icol_local) = last_norm(icol_local)*h_approx(i - 1, 1, icol_local)
886 conv_norm = max(conv_norm, abs(results(icol_local)))
889 CALL para_env%max(conv_norm)
891 IF (conv_norm .LT. eps_exp .OR. i .GT. narnoldi)
THEN
893 mos_new(1)%local_data = rzero
894 mos_new(2)%local_data = rzero
895 DO icol_local = 1, ncol_local
897 prefac = h_approx(idim, 1, icol_local)*norm1(icol_local)
898 mos_new(1)%local_data(:, icol_local) = mos_new(1)%local_data(:, icol_local) + &
899 v_mats(idim)%local_data(:, icol_local)*prefac
900 mos_new(2)%local_data(:, icol_local) = mos_new(2)%local_data(:, icol_local) + &
901 v_mats(idim)%local_data(:, icol_local + ncol_local)*prefac
905 IF (
PRESENT(mos_next))
THEN
906 DO icol_local = 1, ncol_local
909 n(idim, j) = h_approx(idim, j, icol_local)
912 CALL dgemm(
"N",
'N', mydim, mydim, mydim, rone, n(1, 1), mydim, n(1, 1), mydim, rzero, mat1(1, 1), mydim)
915 h_approx(idim, j, icol_local) = mat1(idim, j)
919 mos_next(1)%local_data = rzero
920 mos_next(2)%local_data = rzero
921 DO icol_local = 1, ncol_local
923 prefac = h_approx(idim, 1, icol_local)*norm1(icol_local)
924 mos_next(1)%local_data(:, icol_local) = &
925 mos_next(1)%local_data(:, icol_local) + &
926 v_mats(idim)%local_data(:, icol_local)*prefac
927 mos_next(2)%local_data(:, icol_local) = &
928 mos_next(2)%local_data(:, icol_local) + &
929 v_mats(idim)%local_data(:, icol_local + ncol_local)*prefac
933 IF (conv_norm .LT. eps_exp)
THEN
946 IF (convergence)
EXIT
949 IF (.NOT. convergence) &
950 cpwarn(
"ARNOLDI method did not converge")
953 CALL cp_fm_release(v_mats)
955 CALL col_group%free()
957 DEALLOCATE (h_approx)
958 DEALLOCATE (h_approx_save)
961 DEALLOCATE (last_norm)
962 CALL timestop(handle)
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
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_solve(matrix_a, general_a, determinant)
Solve the system of linear equations A*b=A_general using LU decomposition. Pay attention that both ma...
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_set_all(matrix, alpha, beta)
Set all elements of the full matrix to alpha. Besides, set all diagonal matrix elements to beta (if g...
basic linear algebra operations for full matrices
subroutine, public cp_fm_solve(matrix_a, general_a)
computes the the solution to A*b=A_general using lu decomposition pay attention, both matrices are ov...
subroutine, public cp_complex_fm_gemm(transa, transb, m, n, k, alpha, A_re, A_im, B_re, B_im, beta, C_re, C_im, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, c_first_row)
Convenience function. Computes the matrix multiplications needed for the multiplication of complex ma...
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
represent the structure of a full matrix
subroutine, public cp_fm_struct_double(fmstruct, struct, context, col, row)
creates a struct with twice the number of blocks on each core. If matrix A has to be multiplied with ...
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
real(kind=dp), dimension(0:maxfac), parameter, public fac
complex(kind=dp), parameter, public z_zero
Routines for calculating a complex matrix exponential.
subroutine, public get_nsquare_norder(norm, nsquare, norder, eps_exp, method, do_emd)
optimization function for pade/taylor order and number of squaring steps
subroutine, public exp_pade_only_imaginary(exp_H, im_part, nsquare, npade)
exponential of a complex matrix, calculated using pade approximation together with scaling and squari...
subroutine, public taylor_only_imaginary(exp_H, im_matrix, nsquare, ntaylor)
specialized subroutine for purely imaginary matrix exponentials
subroutine, public taylor_full_complex(exp_H, re_part, im_part, nsquare, ntaylor)
subroutine for general complex matrix exponentials on input a separate cp_fm_type for real and comple...
subroutine, public exp_pade_real(exp_H, matrix, nsquare, npade)
exponential of a real matrix, calculated using pade approximation together with scaling and squaring
subroutine, public exp_pade_full_complex(exp_H, re_part, im_part, nsquare, npade)
exponential of a complex matrix, calculated using pade approximation together with scaling and squari...
subroutine, public arnoldi(mos_old, mos_new, eps_exp, Hre, Him, mos_next, narn_old)
exponential of a complex matrix, calculated using arnoldi subspace method (directly applies to the MO...
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes