def S2Proj(Quket, Q, threshold=1e-8): """Function Perform spin-projection to QuantumState |Q> |Q'> = Ps |Q> where Ps is a spin-projection operator (non-unitary). Ps = \sum_i^ng wg[i] Ug[i] This function provides a shortcut to |Q'>, which is unreal. One actually needs to develop a quantum circuit for this (See PRR 2, 043142 (2020)). Author(s): Takashi Tsuchimochi """ spin = Quket.projection.spin s = (spin - 1) / 2 Ms = Quket.projection.Ms / 2 n_qubits = Q.get_qubit_count() state_P = QuantumState(n_qubits) state_P.multiply_coef(0) nalpha = max(Quket.projection.euler_ngrids[0], 1) nbeta = max(Quket.projection.euler_ngrids[1], 1) ngamma = max(Quket.projection.euler_ngrids[2], 1) for ialpha in range(nalpha): alpha = Quket.projection.sp_angle[0][ialpha] alpha_coef = Quket.projection.sp_weight[0][ialpha] * np.exp( 1j * alpha * Ms) for ibeta in range(nbeta): beta = Quket.projection.sp_angle[1][ibeta] beta_coef = (Quket.projection.sp_weight[1][ibeta] * Quket.projection.dmm[ibeta]) for igamma in range(ngamma): gamma = Quket.projection.sp_angle[2][igamma] gamma_coef = (Quket.projection.sp_weight[2][igamma] * np.exp(1j * gamma * Ms)) # Total Weight coef = (2 * s + 1) / (8 * np.pi) * (alpha_coef * beta_coef * gamma_coef) state_g = QuantumState(n_qubits) state_g.load(Q) circuit_Rg = QuantumCircuit(n_qubits) set_circuit_Rg(circuit_Rg, n_qubits, alpha, beta, gamma) circuit_Rg.update_quantum_state(state_g) state_g.multiply_coef(coef) state_P.add_state(state_g) # Normalize norm2 = state_P.get_squared_norm() if norm2 < threshold: error( "Norm of spin-projected state is too small!\n", "This usually means the broken-symmetry state has NO component ", "of the target spin.") state_P.normalize(norm2) # print_state(state_P,name="P|Q>",threshold=1e-6) return state_P
def NProj(Quket, Q, threshold=1e-8): """Function Perform number-projection to QuantumState |Q> |Q'> = PN |Q> where PN is a number-projection operator (non-unitary). PN = \sum_i^ng wg[i] Ug[i] This function provides a shortcut to |Q'>, which is unreal. One actually needs to develop a quantum circuit for this (See QST 6, 014004 (2021)). Author(s): Takashi Tsuchimochi """ n_qubits = Q.get_qubit_count() state_P = QuantumState(n_qubits) state_P.multiply_coef(0) state_g = QuantumState(n_qubits) nphi = max(Quket.projection.number_ngrids, 1) #print_state(Q) for iphi in range(nphi): coef = (Quket.projection.np_weight[iphi] * np.exp(1j * Quket.projection.np_angle[iphi] * (Quket.projection.n_active_electrons - Quket.projection.n_active_orbitals))) state_g = Q.copy() circuit = QuantumCircuit(n_qubits) set_circuit_ExpNa(circuit, n_qubits, Quket.projection.np_angle[iphi]) set_circuit_ExpNb(circuit, n_qubits, Quket.projection.np_angle[iphi]) circuit.update_quantum_state(state_g) state_g.multiply_coef(coef) state_P.add_state(state_g) norm2 = state_P.get_squared_norm() if norm2 < threshold: error( "Norm of number-projected state is too small!\n", "This usually means the broken-symmetry state has NO component ", "of the target number.") state_P.normalize(norm2) return state_P
def cost_jmucc(Quket, print_level, theta_lists): """Function Cost function of Jeziorski-Monkhorst UCCSD. Author(s): Yuto Mori, Takashi Tsuchimochi """ t1 = time.time() noa = Quket.noa nob = Quket.nob nva = Quket.nva nvb = Quket.nvb nocc = noa + nob n_electrons = Quket.n_electrons n_qubits = Quket.n_qubits nstates = len(Quket.multi.weights) ndim1 = Quket.ndim1 ndim2 = Quket.ndim2 ndim = Quket.ndim ndim_i = ndim1 + ndim2 rho = Quket.rho DS = Quket.DS det = Quket.det occ_lists = [] vir_lists = [] for istate in range(nstates): ### Read state integer and extract occupied/virtual info occ_list_tmp = int2occ(Quket.multi.states[istate]) vir_list_tmp = [i for i in range(n_qubits) if i not in occ_list_tmp] occ_lists.extend(occ_list_tmp) vir_lists.extend(vir_list_tmp) ### Prepare kappa_lists kappa_lists = [] for istate in range(nstates): kappa_list = create_kappalist( ndim1, occ_lists[nocc * istate:nocc * (istate + 1)], noa, nob, nva, nvb) kappa_lists.extend(kappa_list) ### Prepare JM basis states = [] for istate in range(nstates): det = Quket.multi.states[istate] state = create_uccsd_state(n_qubits, rho, DS, theta_lists[ndim_i * istate:ndim_i * (istate + 1)], det, ndim1, SpinProj=Quket.projection.SpinProj) #prints('\n State {}?'.format(istate)) #print_state(state) states.append(state) H, S2, S = create_HS2S(Quket, states) #invS = np.linalg.inv(S) #H_invS = np.dot(invS, H) #np.set_printoptions(precision=17) #en,cvec = np.linalg.eig(H_invS) #printmat(en, name="energy") #printmat(cvec, name="cvec") root_invS = root_inv(S.real) H_ortho = root_invS.T @ H @ root_invS nstates0 = root_invS.shape[1] #print(nstates0) en, dvec = np.linalg.eig(H_ortho) ind = np.argsort(en.real, -1) en = en.real[ind] dvec = dvec[:, ind] #printmat(en, name="energy") #printmat(dvec, name="dvec") cvec = root_invS @ dvec # Renormalize # Sdig =cvec.T@S@cvec #printmat(Sdig,name="Sdig") # for istate in range(nstates): # cvec[:,istate] = cvec[:,istate] / np.sqrt(Sdig[istate,istate].real) # Compute <S**2> of each state S2dig = cvec.T @ S2 @ cvec #printmat(S2dig) s2 = [] for istate in range(nstates0): s2.append(S2dig[istate, istate].real) # compute <S**2> for each state t2 = time.time() cpu1 = t2 - t1 if print_level == 1: cput = t2 - cf.t_old cf.t_old = t2 cf.icyc += 1 prints(f"{cf.icyc:5d}:", end="") for istate in range(nstates0): prints( f"E[{istate}] = {en[istate]:.8f} " f"(<S**2> = {s2[istate]:7.5f}) ", end="") prints(f"CPU Time = {cput:5.2f} ({cpu1:2.2f} / step)") SaveTheta(ndim, theta_lists, cf.tmp) # cf.iter_threshold = 0 if print_level > 1: cput = t2 - cf.t_old cf.t_old = t2 prints("Final:", end="") for istate in range(nstates0): prints( f"E[{istate}] = {en[istate]:.8f} " f"(<S**2> = {s2[istate]:7.5f}) ", end="") prints(f"CPU Time = {cput:5.2f} ({cpu1:2.2f} / step)") prints("\n------------------------------------") for istate in range(nstates): prints(f"JM Basis {istate}") print_state(states[istate]) prints("") printmat(cvec.real, name="Coefficients: ") prints("------------------------------------\n\n") prints("###############################################") prints("# JM states #") prints("###############################################", end="") for istate in range(nstates0): prints("") prints(f"State : {istate}") prints(f"E : {en[istate]:.8f}") prints(f"<S**2> : {s2[istate]:.5f}") prints(f"Superposition:") spstate = QuantumState(n_qubits) spstate.multiply_coef(0) for jstate in range(nstates0): state = states[jstate].copy() coef = cvec[jstate, istate] state.multiply_coef(coef) spstate.add_state(state) print_state(spstate) prints("###############################################") cost = np.sum(Quket.multi.weights * en) norm = np.sum(Quket.multi.weights) cost /= norm return cost, s2
def cost_ic_mrucc_spinfree(Quket, print_level, theta_list): """ Function Author(s): Yuto Mori """ t1 = time.time() nstates = Quket.multi.nstates n_qubits = Quket.n_qubits ndim = Quket.ndim ndim1 = Quket.ndim1 rho = Quket.rho DS = Quket.DS v_n, a_n, c_n = calc_num_v_a_c(Quket) states = [] for istate in range(nstates): det = Quket.multi.states[istate] state = create_icmr_uccsd_state_spinfree( n_qubits, v_n, a_n, c_n, rho, DS, theta_list, det, ndim1, act2act=Quket.multi.act2act_opt, SpinProj=Quket.projection.SpinProj) states.append(state) H, S2, S = create_HS2S(Quket, states) root_invS = root_inv(S.real) H_ortho = root_invS.T @ H @ root_invS nstates0 = root_invS.shape[1] en, dvec = np.linalg.eig(H_ortho) idx = np.argsort(en.real, -1) en = en.real[idx] dvec = dvec[:, idx] cvec = root_invS @ dvec S2dig = cvec.T @ S2 @ cvec s2 = [S2dig[i, i].real for i in range(nstates0)] t2 = time.time() cpu1 = t2 - t1 if print_level == 1: cput = t2 - cf.t_old cf.t_old = t2 cf.icyc += 1 prints(f"{cf.icyc:5d}: ", end="") for istate in range(nstates0): prints( f"E[{istate}] = {en[istate]:.8f} " f"(<S**2> = {s2[istate]:7.5f}) ", end="") prints(f"CPU Time = {cput:5.2f} ({cpu1:2.2f} / step)") SaveTheta(ndim, theta_list, cf.tmp) # cf.iter_threshold = 0 if print_level > 1: cput = t2 - cf.t_old cf.t_old = t2 prints("Final: ", end="") for istate in range(nstates0): prints( f"E[{istate}] = {en[istate]:.8f} " f"(<S**2> = {s2[istate]:7.5f}) ", end="") prints(f"CPU Time = {cput:5.2f} ({cpu1:2.2f} / step)\n") prints("------------------------------------") for istate in range(nstates): prints(f"ic Basis {istate}") print_state(states[istate]) prints("") printmat(cvec.real, name="Coefficients: ") prints("------------------------------------\n\n") prints("###############################################") prints("# ic states #") prints("###############################################", end="") for istate in range(nstates0): prints("") prints(f"State : {istate}") prints(f"E : {en[istate]:.8f}") prints(f"<S**2> : {s2[istate]:.5f}") prints(f"Superposition : ") spstate = QuantumState(n_qubits) spstate.multiply_coef(0) for jstate in range(nstates0): state = states[jstate].copy() coef = cvec[jstate, istate] state.multiply_coef(coef) spstate.add_state(state) print_state(spstate) prints("###############################################") cost = np.sum(Quket.multi.weights * en) norm = np.sum(Quket.multi.weights) cost /= norm return cost, s2
def cost_ic_mrucc(Quket, print_level, qulacs_hamiltonian, qulacs_s2, theta_list): """ Function Author(s): Yuto Mori """ from .init import int2occ from .jmucc import create_HS2S t1 = time.time() #nstates = len(cf.multi_weights) # nc = n_qubit_system # vir_index = 0 # for istate in range(nstates): # ### Read state integer and extract occupied/virtual info # occ_list_tmp = int2occ(cf.multi_states[istate]) # vir_tmp = occ_list_tmp[-1] + 1 # for ii in range(len(occ_list_tmp)): # if ii == occ_list_tmp[ii]: core_tmp = ii + 1 # vir_index = max(vir_index,vir_tmp) # nc = min(nc,core_tmp) # nv = n_qubit_system - vir_index # na = n_qubit_system - nc - nv #ndim1, ndim2 = calncum_ic_theta(n_qubit_system,nv,na,nc) nca = ncb = 0 noa = Quket.noa nob = Quket.nob nva = Quket.nva nvb = Quket.nvb ndim1 = Quket.ndim1 ndim2 = Quket.ndim2 ndim = Quket.ndim nstates = Quket.Multi.nstates # assume that nca = ncb, noa = nob and nva = nvb nc = nca no = noa nv = nva states = [] for istate in range(nstates): det = cf.multi_states[istate] state = create_icmr_uccsd_state(n_qubit_system, nv, na, nc, rho, DS, theta_list, det, ndim1) states.append(state) H, S2, S = create_HS2S(qulacs_hamiltonian, qulacs_s2, states) root_invS = root_inv(S.real) H_ortho = root_invS.T @ H @ root_invS nstates0 = root_invS.shape[1] en, dvec = np.linalg.eig(H_ortho) idx = np.argsort(en.real, -1) en = en.real[idx] dvec = dvec[:, idx] cvec = root_invS @ dvec S2dig = cvec.T @ S2 @ cvec s2 = [S2dig[i, i].real for i in range(nstates0)] t2 = time.time() cpu1 = t2 - t1 if print_level == 1: cput = t2 - cf.t_old cf.t_old = t2 cf.icyc += 1 prints(f"{cf.icyc:5d}: ", end="") for istate in range(nstates0): prints( f"E[{istate}] = {en[istate]:.8f} " f"(<S**2> = {s2[istate]:7.5f}) ", end="") prints(f"CPU Time = {cput:5.2f} ({cpu1:2.2f} / step)") SaveTheta(ndim, theta_list, cf.tmp) # cf.iter_threshold = 0 if print_level > 1: cput = t2 - cf.t_old cf.t_old = t2 prints("Final: ", end="") for istate in range(nstates0): prints( f"E[{istate}] = {en[istate]:.8f} " f"(<S**2> = {s2[istate]:7.5f}) ", end="") prints(f"CPU Time = {cput:5.2f} ({cpu1:2.2f} / step)\n") prints("------------------------------------") for istate in range(nstates): prints(f"ic Basis {istate}") print_state(states[istate]) prints("") printmat(cvec.real, name="Coefficients: ") prints("------------------------------------\n\n") prints("###############################################") prints("# ic states #") prints("###############################################", end="") for istate in range(nstates0): prints("") prints(f"State : {istate}") prints(f"E : {en[istate]:.8f}") prints(f"<S**2> : {s2[istate]:.5f}") prints(f"Superposition : ") spstate = QuantumState(n_qubit_system) spstate.multiply_coef(0) for jstate in range(nstates0): state = states[jstate].copy() coef = cvec[jstate, istate] state.multiply_coef(coef) spstate.add_state(state) print_state(spstate) prints("###############################################") cost = norm = 0 norm = np.sum(Quket.multi.weights) cost = np.sum(Quket.multi.weights * en) cost /= norm return cost, s2