mirror of
https://gitlab.com/scemama/qp_plugins_scemama.git
synced 2024-12-22 20:34:05 +01:00
224 lines
8.7 KiB
Python
224 lines
8.7 KiB
Python
# !!!
|
|
import sys, os
|
|
#QMCCHEM_PATH=os.environ["QMCCHEM_PATH"]
|
|
#sys.path.insert(0,QMCCHEM_PATH+"/EZFIO/Python/")
|
|
# !!!
|
|
from ezfio import ezfio
|
|
from math import sqrt
|
|
from datetime import datetime
|
|
import time
|
|
import numpy as np
|
|
import subprocess
|
|
from scipy.linalg import eig, eigh
|
|
from RSVD import powit_RSVD
|
|
|
|
|
|
|
|
# ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~
|
|
def get_Hsvd_QP(Hsvd_qp_txt):
|
|
Hsvd_qp = np.zeros( (n_svd,n_svd) )
|
|
Hsvd_qp_file = open(Hsvd_qp_txt, 'r')
|
|
for line in Hsvd_qp_file:
|
|
line = line.split()
|
|
i = int(line[0]) - 1
|
|
j = int(line[1]) - 1
|
|
Hsvd_qp[i,j] = float(line[2])
|
|
return(Hsvd_qp)
|
|
# ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~
|
|
|
|
|
|
|
|
|
|
|
|
# ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~
|
|
def get_Hpostsvd_QP(Hpostsvd_qp_txt):
|
|
Hpostsvd_qp = np.zeros( (n_svd*n_svd,n_svd*n_svd) )
|
|
Hpostsvd_qp_file = open(Hpostsvd_qp_txt, 'r')
|
|
for line in Hpostsvd_qp_file:
|
|
line = line.split()
|
|
i = int(line[0]) - 1
|
|
j = int(line[1]) - 1
|
|
Hpostsvd_qp[i,j] = float(line[2])
|
|
return(Hpostsvd_qp)
|
|
# ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~
|
|
|
|
|
|
|
|
|
|
|
|
# ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~
|
|
def get_Esvd_QP(Hsvd_qp):
|
|
# symmetrise and diagonalise
|
|
aa = Hsvd_qp
|
|
aa = 0.5*( aa + aa.T )
|
|
bb = np.identity(n_svd)
|
|
#eigvals_svd, vr = eig(aa, bb, left=False, right=True, overwrite_a=True, overwrite_b=True,
|
|
eigvals_svd, vr = eig(aa, left=False, right=True, overwrite_a=True, overwrite_b=True,
|
|
check_finite=True, homogeneous_eigvals=False)
|
|
recouvre_svd = np.abs(psi_svd_coeff @ vr)
|
|
ind_gssvd = np.argmax(recouvre_svd)
|
|
E_svd = eigvals_svd[ind_gssvd] + E_toadd
|
|
return( E_svd, vr[:,ind_gssvd] )
|
|
# ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~
|
|
|
|
|
|
|
|
# ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~
|
|
def get_Epostsvd_QP(Hpostsvd_qp):
|
|
# symmetrise and diagonalise
|
|
aa = Hpostsvd_qp
|
|
aa = 0.5*( aa + aa.T )
|
|
bb = np.identity(n_svd*n_svd)
|
|
eigvals_postsvd, vr = eig(aa, bb, left=False, right=True, overwrite_a=True, overwrite_b=True,
|
|
check_finite=True, homogeneous_eigvals=False)
|
|
d_postsvd = np.diagflat(psi_svd_coeff)
|
|
d_postsvd = d_postsvd.reshape( (1,n_svd*n_svd) )
|
|
recouvre_postsvd = np.abs(d_postsvd @ vr)
|
|
ind_gspostsvd = np.argmax(recouvre_postsvd)
|
|
# !!!
|
|
E_postsvd = eigvals_postsvd[ind_gspostsvd] + E_toadd
|
|
# !!!
|
|
return( E_postsvd, vr[:,ind_gspostsvd] )
|
|
# ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~
|
|
|
|
|
|
|
|
# ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~
|
|
def SVD_postsvd(sigma_postsvd):
|
|
# !!!
|
|
print(' performing new SVD for the post SVD eigenvector:' )
|
|
# !!!
|
|
sigma_postsvd_mat = np.zeros( (n_svd,n_svd) )
|
|
for indc in range(1, n_svd**2+1):
|
|
if( ( indc % n_svd ) !=0 ):
|
|
kp = indc % n_svd
|
|
else:
|
|
kp = n_svd
|
|
indc1 = int( ( indc - kp ) / n_svd )
|
|
k = indc1 % n_svd + 1
|
|
irow = kp + (k-1)*n_svd - 1
|
|
sigma_postsvd_mat[kp-1][k-1] = sigma_postsvd[irow]
|
|
sigma_postsvd = sigma_postsvd_mat
|
|
print(sigma_postsvd[0:n_svd,0:n_svd])
|
|
# !!!
|
|
# construct the new matrix Y
|
|
Y = np.dot( U_svd , np.dot(sigma_postsvd , V_svd.T) )
|
|
normY = np.linalg.norm(Y, ord='fro')
|
|
# !!!
|
|
# parameters of RSVD
|
|
rank = n_svd
|
|
npow = 10
|
|
nb_oversamp = 10
|
|
# !!!
|
|
# call RSV
|
|
U_postSVD, sigma_postsvd_diag, VT_postsvd = powit_RSVD(Y, rank, npow, nb_oversamp)
|
|
# !!!
|
|
# check precision
|
|
Y_SVD = np.dot( U_postSVD , np.dot( np.diag(sigma_postsvd_diag) , VT_postsvd ) )
|
|
energy = np.sum( np.square(sigma_postsvd_diag) ) / normY**2
|
|
err_SVD = 100. * np.linalg.norm( Y - Y_SVD, ord="fro") / normY
|
|
print(' energy = {}, error = {}\n'.format(energy, err_SVD))
|
|
# !!!
|
|
return(U_postSVD, sigma_postsvd_diag, VT_postsvd)
|
|
# !!!
|
|
# ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~ ! ~
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
t0 = time.time()
|
|
# !!!
|
|
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ #
|
|
EZFIO_file = "/home/aammar/qp2/src/svdwf/2h2_cisd_nsvd20"
|
|
Hsvd_qp_txt = 'H_QP_svd_2h2_nsvd20.txt'
|
|
Hpostsvd_qp_txt = 'H_QP_postsvd_2h2_nsvd20.txt'
|
|
# h2o
|
|
#E_toadd = 9.194966082434476 #6.983610961797779
|
|
# 2h2
|
|
E_toadd = 1.711353545183182
|
|
# f2
|
|
#E_toadd = 30.35863309325590
|
|
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ #
|
|
# !!!
|
|
ezfio.set_file(EZFIO_file)
|
|
n_svd = ezfio.get_spindeterminants_n_svd_coefs()
|
|
psi_svd_coeff = np.array(ezfio.get_spindeterminants_psi_svd_coefs())
|
|
U_svd = np.array(ezfio.get_spindeterminants_psi_svd_alpha())
|
|
V_svd = np.array(ezfio.get_spindeterminants_psi_svd_beta())
|
|
# !!!
|
|
U_svd = U_svd[0,:,:].T
|
|
V_svd = V_svd[0,:,:].T
|
|
# !!!
|
|
print(" Today's date:", datetime.now() )
|
|
print(" EZFIO file = {}".format(EZFIO_file))
|
|
print(" n_svd = {}\n".format(n_svd) )
|
|
# !!!
|
|
print(' initial svd coeff = {}\n'.format(psi_svd_coeff))
|
|
C_old = np.dot( U_svd , np.dot( np.diagflat(psi_svd_coeff) , V_svd.T ) )
|
|
norm_C = np.linalg.norm(C_old, ord="fro")
|
|
# !!!
|
|
read_QPsvd = 'y'
|
|
if( read_QPsvd == 'y' ):
|
|
Hsvd_qp = get_Hsvd_QP(Hsvd_qp_txt)
|
|
E_svd_QP, sigma_svd_QP = get_Esvd_QP(Hsvd_qp)
|
|
print(' QP svd enegry = {}'.format(E_svd_QP) )
|
|
sigma_svd_QP = sigma_svd_QP * np.sign(sigma_svd_QP[0])
|
|
print(' QP svd coeff = {}\n'.format(sigma_svd_QP))
|
|
# compare C_new and C_old
|
|
C_new = np.dot( U_svd , np.dot( np.diagflat(sigma_svd_QP) , V_svd.T ) )
|
|
delta_C = 100. * np.linalg.norm(C_old-C_new, ord="fro") / norm_C
|
|
print(' Difference between C_old and C_new svd = {} %\n'.format(delta_C))
|
|
# !!!
|
|
read_QPpostsvd = 'y'
|
|
if( read_QPpostsvd == 'y' ):
|
|
Hpostsvd_qp = get_Hpostsvd_QP(Hpostsvd_qp_txt)
|
|
E_postsvd_QP, sigma_postsvd_QP = get_Epostsvd_QP(Hpostsvd_qp)
|
|
print(' QP postsvd enegry = {}'.format(E_postsvd_QP) )
|
|
U_postSVD, sigma_postsvd_diag, Vt_postSVD = SVD_postsvd(sigma_postsvd_QP)
|
|
V_postSVD = Vt_postSVD.T
|
|
print(' QP postsvd coeff = {}\n'.format(sigma_postsvd_diag))
|
|
# compare C_new and C_old
|
|
C_new = np.dot( U_postSVD , np.dot( np.diag(sigma_postsvd_diag) , Vt_postSVD ) )
|
|
delta_C_m = 100. * np.linalg.norm(C_old-C_new, ord="fro") / norm_C
|
|
delta_C_p = 100. * np.linalg.norm(C_old+C_new, ord="fro") / norm_C
|
|
delta_C = min(delta_C_m,delta_C_p)
|
|
print(' Difference between C_old and C_new postsvd = {} %'.format(delta_C))
|
|
# !!!
|
|
# !!!
|
|
# ___________________________________________________________________________
|
|
# ___________________________________________________________________________
|
|
#
|
|
save_to_EZFIO = ''
|
|
#
|
|
if( save_to_EZFIO == 'svd'):
|
|
ezfio.set_spindeterminants_psi_svd_coefs( sigma_svd_QP )
|
|
direc_svdcoeff = EZFIO_file + '/spindeterminants/psi_svd_coefs.gz'
|
|
print(' {} is modified'.format(direc_svdcoeff) )
|
|
# # #
|
|
elif( save_to_EZFIO == 'postsvd' ):
|
|
U_postSVD_toEZFIO = np.zeros( ( 1, U_postSVD.shape[1], U_postSVD.shape[0] ) )
|
|
V_postSVD_toEZFIO = np.zeros( ( 1, V_postSVD.shape[1], V_postSVD.shape[0] ) )
|
|
U_postSVD_toEZFIO[0,:,:] = U_postSVD.T
|
|
V_postSVD_toEZFIO[0,:,:] = V_postSVD.T
|
|
#
|
|
ezfio.set_spindeterminants_psi_svd_alpha( U_postSVD_toEZFIO )
|
|
ezfio.set_spindeterminants_psi_svd_coefs( sigma_postsvd_diag )
|
|
ezfio.set_spindeterminants_psi_svd_beta( V_postSVD_toEZFIO )
|
|
#
|
|
direc_svdcoeff = EZFIO_file + '/spindeterminants/psi_svd_coefs.gz'
|
|
direc_svdalpha = EZFIO_file + '/spindeterminants/psi_svd_alpha.gz'
|
|
direc_svdbeta = EZFIO_file + '/spindeterminants/psi_svd_beta.gz'
|
|
print(' {} is modified'.format(direc_svdcoeff) )
|
|
print(' {} is modified'.format(direc_svdalpha) )
|
|
print(' {} is modified'.format(direc_svdbeta ) )
|
|
else:
|
|
pass
|
|
# ___________________________________________________________________________
|
|
# ___________________________________________________________________________
|
|
#
|
|
print("end after {:.3f} minutes".format((time.time()-t0)/60.) )
|
|
# !!!
|
|
# !!!
|