def test_bellpair() -> None: state = QuantumState(2) circ = Circuit(2).H(0).CX(0, 1) qulacs_circ = tk_to_qulacs(circ) qulacs_circ.update_quantum_state(state) state0 = QuantumState(2) state0.set_computational_basis(0) probability = inner_product(state0, state)**2 assert np.isclose(probability, 0.5) state1 = QuantumState(2) state1.set_computational_basis(1) probability = inner_product(state1, state)**2 assert np.isclose(probability, 0) state2 = QuantumState(2) state2.set_computational_basis(2) probability = inner_product(state2, state)**2 assert np.isclose(probability, 0) state3 = QuantumState(2) state3.set_computational_basis(3) probability = inner_product(state3, state)**2 assert np.isclose(probability, 0.5)
def test_H() -> None: state = QuantumState(1) state.set_zero_state() circ = Circuit(1).H(0) qulacs_circ = tk_to_qulacs(circ) qulacs_circ.update_quantum_state(state) state0 = QuantumState(1) state0.set_computational_basis(0) probability = inner_product(state0, state)**2 assert np.isclose(probability, 0.5)
def test_CU_Y0Y1(self): n_qubits = 3 a_idx = 2 theta = np.pi/4 state = QuantumState(n_qubits) input_states_bin = [0b001, 0b010, 0b101, 0b110] input_states = [] output_states = [] circuit = QuantumCircuit(n_qubits) # change basis from Z to Y circuit.add_S_gate(0) circuit.add_S_gate(1) circuit.add_H_gate(0) circuit.add_H_gate(1) circuit.add_CNOT_gate(1, 0) # RZ circuit.add_RZ_gate(0, -0.5*theta) circuit.add_CNOT_gate(a_idx, 0) circuit.add_RZ_gate(0, 0.5*theta) circuit.add_CNOT_gate(a_idx, 0) circuit.add_CNOT_gate(1, 0) # change basis from Z to Y circuit.add_H_gate(0) circuit.add_H_gate(1) circuit.add_Sdag_gate(0) circuit.add_Sdag_gate(1) for b in input_states_bin: psi = state.copy() psi.set_computational_basis(b) input_states += [psi] psi_out = psi.copy() circuit.update_quantum_state(psi_out) output_states += [psi_out] p_list = [] for in_state in input_states: for out_state in output_states: prod = inner_product(in_state, out_state) p_list += [prod] # |001> exp_list = [1.0, 0.0, 0.0, 0.0] # |010> exp_list += [0.0, 1.0, 0.0, 0.0] # |101> exp_list += [0.0, 0.0, np.cos(theta/2), complex(0, -np.sin(theta/2))] # |110> exp_list += [0.0, 0.0, complex(0, -np.sin(theta/2)), np.cos(theta/2)] for result, expected in zip(p_list, exp_list): self.assertAlmostEqual(result, expected, places=6)
def orthogonal_constraint(Quket, state): """Function Compute the penalty term for excited states based on 'orthogonally-constrained VQE' scheme. """ nstates = len(Quket.lower_states) extra_cost = 0 for i in range(nstates): Ei = Quket.qulacs.Hamiltonian.get_expectation_value( Quket.lower_states[i]) overlap = inner_product(Quket.lower_states[i], state) extra_cost += -Ei * abs(overlap)**2 return extra_cost
def expval(self, observable, wires, par): bra = self._state.copy() if isinstance(observable, list): A = self._get_tensor_operator_matrix(observable, par) wires = [item for sublist in wires for item in sublist] else: A = self._get_operator_matrix(observable, par) dense_gate = gate.DenseMatrix(wires, A) dense_gate.update_quantum_state(self._state) expectation = inner_product(bra, self._state) return expectation.real
def create_HS2S(QuketData, states): X_num = len(states) H = np.zeros((X_num, X_num), dtype=np.complex) S2 = np.zeros((X_num, X_num), dtype=np.complex) S = np.zeros((X_num, X_num), dtype=np.complex) for i in range(X_num): for j in range(i + 1): H[i, j] = QuketData.qulacs.Hamiltonian.get_transition_amplitude( states[i], states[j]) S2[i, j] = QuketData.qulacs.S2.get_transition_amplitude( states[i], states[j]) S[i, j] = inner_product(states[i], states[j]) H[:i, i] = H[i, :i] S2[:i, i] = S2[i, :i] S[:i, i] = S[i, :i] return H, S2, S
def test_prepstate(self): n_qubit = 4 dim = 2**n_qubit from qulacs import QuantumState from qulacs.state import inner_product s0 = QuantumState(n_qubit) s0.set_Haar_random_state() s1 = freqerica.circuit.universal.prepstate(n_qubit, s0.get_vector()) print(inner_product(s0, s1)) civec = {0b0011: .5, 0b0101: +.5j, 0b1001: -.5j, 0b0110: -.5} s2 = freqerica.circuit.universal.prepstate(n_qubit, civec) print(s2) assert True
def Orthonormalize(state0, state1, normalize=True): """Function Project out state 0 from state 1 |1> <= (1 - |0><0| ) |1> |1> is renormalized. Author(s): Takashi Tsuchimochi """ S01 = inner_product(state0, state1) tmp = state0.copy() tmp.multiply_coef(-S01) state1.add_state(tmp) if normalize: # Normalize norm2 = state1.get_squared_norm() state1.normalize(norm2)
def test_CU_Z0(self): n_qubits = 2 a_idx = 1 theta = np.pi/8 state = QuantumState(n_qubits) input_states_bin = [0b00, 0b10] input_states = [] output_states = [] circuit_H = QuantumCircuit(n_qubits) circuit_H.add_H_gate(0) # |0>|+> and |1>|+> for b in input_states_bin: psi = state.copy() psi.set_computational_basis(b) input_states += [psi] circuit_H.update_quantum_state(psi) circuit = QuantumCircuit(n_qubits) circuit.add_RZ_gate(0, -0.5*theta) circuit.add_CNOT_gate(a_idx, 0) circuit.add_RZ_gate(0, 0.5*theta) circuit.add_CNOT_gate(a_idx, 0) for in_state in input_states: psi = in_state.copy() circuit.update_quantum_state(psi) output_states += [psi] p_list = [] for in_state in input_states: for out_state in output_states: p_list += [inner_product(in_state, out_state)] # <0|<+|0>|+> = 1 # <0|<+|1>|H> = 0 # <1|<+|0>|+> = 0 # <1|<+|1>|H> = cos(pi/16) exp_list = [1.0, 0.0, 0.0, np.cos(theta/2)] for result, expected in zip(p_list, exp_list): self.assertAlmostEqual(result, expected, places=6)
def test_ibm_gateset() -> None: state = QuantumState(3) state.set_zero_state() circ = Circuit(3) circ.add_gate(OpType.U1, 0.19, [0]) circ.add_gate(OpType.U2, [0.19, 0.24], [1]) circ.add_gate(OpType.U3, [0.19, 0.24, 0.32], [2]) qulacs_circ = tk_to_qulacs(circ) qulacs_circ.update_quantum_state(state) state1 = QuantumState(3) state1.set_zero_state() qulacs_circ1 = QuantumCircuit(3) qulacs_circ1.add_U1_gate(0, 0.19 * np.pi) qulacs_circ1.add_U2_gate(1, 0.19 * np.pi, 0.24 * np.pi) qulacs_circ1.add_U3_gate(2, 0.19 * np.pi, 0.24 * np.pi, 0.32 * np.pi) qulacs_circ1.update_quantum_state(state1) overlap = inner_product(state1, state) assert np.isclose(1, overlap)
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 qite_exact(Quket): nspin = Quket.n_qubits db = Quket.dt ntime = Quket.maxiter qbit = Quket.det observable = Quket.qulacs.Hamiltonian threshold = Quket.ftol active_qubit = [x for x in range(nspin)] n = nspin size = 4**nspin index = np.arange(n) delta = QuantumState(n) first_state = QuantumState(n) first_state.set_computational_basis(qbit) prints(f"Exact QITE: Pauli operator group size = {size}") energy = [] psi_dash = first_state.copy() value = observable.get_expectation_value(psi_dash) energy.append(value) t1 = time.time() cf.t_old = t1 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 = {value:.12f} CPU Time = {cput:5.2f}") if abs(dE) < threshold: break #if t == 0: # xv = np.zeros(size) psi_dash_copy = psi_dash.copy() #mpi.comm.bcast(size, root=0) #S_part = np.zeros((size, size), dtype=complex) #S = np.zeros((size, size), dtype=complex) #sizeT = size*(size+1)//2 #nblock = sizeT//mpi.nprocs #ij = mpi.rank*nblock #start = int(np.sqrt(2*ij + 1/4) - 1/2) #end = int(np.sqrt(2*(ij+nblock) + 1/4) - 1/2) #for i in range(start, end): # for j in range(i+1): # S_part[i, j] = calc_inner1(i, j, n, active_qubit, # index, psi_dash) # ij += 1 # S[:i, i] = S[i, :i] #mpi.comm.Allreduce(S_part, S, mpi.MPI.SUM) S_part = np.zeros((size, size), dtype=complex) S = np.zeros((size, size), dtype=complex) sizeT = size * (size - 1) // 2 ipos, my_ndim = mpi.myrange(sizeT) ij = 0 for i in range(size): for j in range(i): if ij in range(ipos, ipos + my_ndim): S_part[i, j] = calc_inner1(i, j, n, active_qubit, index, psi_dash) S_part[j, i] = S_part[i, j].conjugate() ij += 1 mpi.comm.Allreduce(S_part, S, mpi.MPI.SUM) for i in range(size): S[i, i] = 1 sigma = [] for i in range(size): state_i = make_state1(i, n, active_qubit, index, psi_dash) sigma.append(state_i) delta = calc_delta(psi_dash, observable, n, db) b_l = [] 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) 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, res, rnk, s = lstsq(Amat, b_l, cond=1.0e-8) a = x.copy() ### Just in case, broadcast a... mpi.comm.Bcast(a, root=0) psi_dash = calc_psi(psi_dash_copy, n, index, a, active_qubit) value = observable.get_expectation_value(psi_dash) energy.append(value) dE = energy[t + 1] - energy[t]
def calc_inner1(i, j, n, active_qubit, index, psi_dash): s_i = make_state1(i, n, active_qubit, index, psi_dash) s_j = make_state1(j, n, active_qubit, index, psi_dash) s = inner_product(s_j, s_i) return s