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 qite_anti(Quket, id_set, size): ### Parameter setting ansatz = Quket.ansatz n = Quket.n_qubits db = Quket.dt qbit = Quket.det ntime = Quket.maxiter observable = Quket.qulacs.Hamiltonian S2_observable = Quket.qulacs.S2 threshold = Quket.ftol S2 = 0 prints(f"QITE: Pauli operator group size = {size}") if ansatz != "cite": sigma_list, sigma_ij_index, sigma_ij_coef = qite_s_operators(id_set, n) len_list = len(sigma_list) prints(f" Unique sigma list = {len_list}") index = np.arange(n) delta = QuantumState(n) first_state = QuantumState(n) first_state.set_computational_basis(qbit) energy = [] psi_dash = first_state.copy() t1 = time.time() cf.t_old = t1 En = observable.get_expectation_value(psi_dash) energy.append(En) if S2_observable is not None: S2 = S2_observable.get_expectation_value(psi_dash) dE = 100 for t in range(ntime): t2 = time.time() cput = t2 - cf.t_old cf.t_old = t2 if cf.debug: print_state(psi_dash) prints(f"{t*db:6.2f}: E = {En:.12f} <S**2> = {S2:17.15f} " f"CPU Time = {cput: 5.2f}") if abs(dE) < threshold: break if t == 0: xv = np.zeros(size) T0 = time.time() delta = calc_delta(psi_dash, observable, n, db) T1 = time.time() if ansatz == "cite": delta.add_state(psi_dash) psi_dash = delta.copy() else: #for i in range(size): # pauli_id = id_set[i] # circuit_i = make_gate(n, index, pauli_id) # state_i = psi_dash.copy() # circuit_i.update_quantum_state(state_i) # print(i) # for j in range(i+1): # pauli_id = id_set[j] # circuit_j = make_gate(n, index, pauli_id) # state_j = psi_dash.copy() # circuit_j.update_quantum_state(state_j) # s = inner_product(state_j, state_i) # S[i][j] = s # S[j][i] = s ### Compute Sij as expectation values of sigma_list Sij_list = np.zeros(len_list) Sij_my_list = np.zeros(len_list) ipos, my_ndim = mpi.myrange(len_list) T2 = time.time() for iope in range(ipos, ipos + my_ndim): val = sigma_list[iope].get_expectation_value(psi_dash) Sij_my_list[iope] = val T3 = time.time() mpi.comm.Allreduce(Sij_my_list, Sij_list, mpi.MPI.SUM) T4 = time.time() ### Distribute Sij ij = 0 sizeT = size * (size - 1) // 2 ipos, my_ndim = mpi.myrange(sizeT) S = np.zeros((size, size), dtype=complex) my_S = np.zeros((size, size), dtype=complex) for i in range(size): for j in range(i): if ij in range(ipos, ipos + my_ndim): ind = sigma_ij_index[ij] coef = sigma_ij_coef[ij] my_S[i, j] = coef * Sij_list[ind] my_S[j, i] = my_S[i, j].conjugate() ij += 1 mpi.comm.Allreduce(my_S, S, mpi.MPI.SUM) for i in range(size): S[i, i] = 1 T5 = time.time() sigma = [] for i in range(size): pauli_id = id_set[i] circuit_i = make_gate(n, index, pauli_id) state_i = psi_dash.copy() circuit_i.update_quantum_state(state_i) sigma.append(state_i) T6 = time.time() b_l = np.empty(size) for i in range(size): b_i = inner_product(sigma[i], delta) b_i = -2 * b_i.imag b_l[i] = b_i Amat = 2 * np.real(S) T7 = time.time() zct = b_l @ Amat def cost_fun(vct): return LA.norm(Amat @ vct - b_l)**2 def J_cost_fun(vct): wct = Amat.T @ Amat @ vct return 2.0 * (wct - zct) #x = sp.optimize.minimize(cost_fun, x0=xv, method='Newton-CG', # jac=J_cost_fun, tol=1e-8).x #xv = x.copy() #x = sp.optimize.least_squares(cost_fun, x0=xv, ftol=1e-8).x #xv = x.copy() x, res, rnk, s = lstsq(Amat, b_l, cond=1e-8) a = x.copy() ### Just in case, broadcast a... mpi.comm.Bcast(a, root=0) T8 = time.time() psi_dash = calc_psi_lessH(psi_dash, n, index, a, id_set) T9 = time.time() if cf.debug: prints(f"T0 -> T1 {T1-T0}") prints(f"T1 -> T2 {T2-T1}") prints(f"T2 -> T3 {T3-T2}") prints(f"T3 -> T4 {T4-T3}") prints(f"T4 -> T5 {T5-T4}") prints(f"T5 -> T6 {T6-T5}") prints(f"T6 -> T7 {T7-T6}") prints(f"T7 -> T8 {T8-T7}") prints(f"T8 -> T9 {T9-T8}") En = observable.get_expectation_value(psi_dash) if S2_observable is not None: S2 = S2_observable.get_expectation_value(psi_dash) energy.append(En) dE = energy[t + 1] - energy[t] print_state(psi_dash, name="QITE")
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_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(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