1
0
mirror of https://gitlab.com/scemama/qp_plugins_scemama.git synced 2024-11-07 14:43:41 +01:00
qp_plugins_scemama/devel/svdwf/set_QP_svd.py

224 lines
8.7 KiB
Python
Raw Normal View History

2021-07-28 17:19:18 +02:00
# !!!
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.) )
# !!!
# !!!