def main(): import numpy as np n_qubit = 2 obs = Observable(n_qubit) initial_state = QuantumState(n_qubit) obs.add_operator(1, "Z 0 Z 1") circuit_list = [] p_list = [0.02, 0.04, 0.06, 0.08] #prepare circuit list for p in p_list: circuit = QuantumCircuit(n_qubit) circuit.add_H_gate(0) circuit.add_RY_gate(1, np.pi / 6) circuit.add_CNOT_gate(0, 1) circuit.add_gate( Probabilistic([p / 4, p / 4, p / 4], [X(0), Y(0), Z(0)])) #depolarizing noise circuit.add_gate( Probabilistic([p / 4, p / 4, p / 4], [X(1), Y(1), Z(1)])) #depolarizing noise circuit_list.append(circuit) #get mitigated output mitigated, non_mitigated_array, fit_coefs = error_mitigation_extrapolate_linear( circuit_list, p_list, initial_state, obs, n_circuit_sample=100000, return_full=True) #plot the result p = np.linspace(0, max(p_list), 100) plt.plot(p, fit_coefs[0] * p + fit_coefs[1], linestyle="--", label="linear fit") plt.scatter(p_list, non_mitigated_array, label="un-mitigated") plt.scatter(0, mitigated, label="mitigated output") #prepare the clean result state = QuantumState(n_qubit) circuit = QuantumCircuit(n_qubit) circuit.add_H_gate(0) circuit.add_RY_gate(1, np.pi / 6) circuit.add_CNOT_gate(0, 1) circuit.update_quantum_state(state) plt.scatter(0, obs.get_expectation_value(state), label="True output") plt.xlabel("error rate") plt.ylabel("expectation value") plt.legend() plt.show()
def test_circuit_add_gate(self): from qulacs import QuantumCircuit, QuantumState from qulacs.gate import Identity, X, Y, Z, H, S, Sdag, T, Tdag, sqrtX, sqrtXdag, sqrtY, sqrtYdag from qulacs.gate import P0, P1, U1, U2, U3, RX, RY, RZ, CNOT, CZ, SWAP, TOFFOLI, FREDKIN, Pauli, PauliRotation from qulacs.gate import DenseMatrix, SparseMatrix, DiagonalMatrix, RandomUnitary, ReversibleBoolean, StateReflection from qulacs.gate import BitFlipNoise, DephasingNoise, IndependentXZNoise, DepolarizingNoise, TwoQubitDepolarizingNoise, AmplitudeDampingNoise, Measurement from qulacs.gate import merge, add, to_matrix_gate, Probabilistic, CPTP, Instrument, Adaptive from scipy.sparse import lil_matrix qc = QuantumCircuit(3) qs = QuantumState(3) ref = QuantumState(3) sparse_mat = lil_matrix((4, 4)) sparse_mat[0, 0] = 1 sparse_mat[1, 1] = 1 def func(v, d): return (v + 1) % d def adap(v): return True gates = [ Identity(0), X(0), Y(0), Z(0), H(0), S(0), Sdag(0), T(0), Tdag(0), sqrtX(0), sqrtXdag(0), sqrtY(0), sqrtYdag(0), Probabilistic([0.5, 0.5], [X(0), Y(0)]), CPTP([P0(0), P1(0)]), Instrument([P0(0), P1(0)], 1), Adaptive(X(0), adap), CNOT(0, 1), CZ(0, 1), SWAP(0, 1), TOFFOLI(0, 1, 2), FREDKIN(0, 1, 2), Pauli([0, 1], [1, 2]), PauliRotation([0, 1], [1, 2], 0.1), DenseMatrix(0, np.eye(2)), DenseMatrix([0, 1], np.eye(4)), SparseMatrix([0, 1], sparse_mat), DiagonalMatrix([0, 1], np.ones(4)), RandomUnitary([0, 1]), ReversibleBoolean([0, 1], func), StateReflection(ref), BitFlipNoise(0, 0.1), DephasingNoise(0, 0.1), IndependentXZNoise(0, 0.1), DepolarizingNoise(0, 0.1), TwoQubitDepolarizingNoise(0, 1, 0.1), AmplitudeDampingNoise(0, 0.1), Measurement(0, 1), merge(X(0), Y(1)), add(X(0), Y(1)), to_matrix_gate(X(0)), P0(0), P1(0), U1(0, 0.), U2(0, 0., 0.), U3(0, 0., 0., 0.), RX(0, 0.), RY(0, 0.), RZ(0, 0.), ] gates.append(merge(gates[0], gates[1])) gates.append(add(gates[0], gates[1])) ref = None for gate in gates: qc.add_gate(gate) for gate in gates: qc.add_gate(gate) qc.update_quantum_state(qs) qc = None qs = None for gate in gates: gate = None gates = None parametric_gates = None
def test_pointer_del(self): from qulacs import QuantumCircuit from qulacs.gate import X qc = QuantumCircuit(1) gate = X(0) qc.add_gate(gate) del gate del qc
def test_add_gate_in_parametric_circuit(self): from qulacs import ParametricQuantumCircuit from qulacs.gate import X circuit = ParametricQuantumCircuit(1) gate = X(0) circuit.add_gate(gate) del gate s = circuit.to_string() del circuit
def test_add_gate(self): from qulacs import QuantumCircuit from qulacs.gate import X circuit = QuantumCircuit(1) gate = X(0) circuit.add_gate(gate) del gate s = circuit.to_string() del circuit
def __qulacs_reset(qstate, qubit_num, q): # error check if q >= qubit_num: raise ValueError("reset qubit id is out of bound") circ = QuantumCircuit(qubit_num) circ.add_gate(Measurement(q, 0)) circ.update_quantum_state(qstate) circ_flip = QuantumCircuit(qubit_num) if qstate.get_classical_value(0) == 1: circ_flip.add_gate(X(q)) circ_flip.update_quantum_state(qstate)
def test_VqeOptimizer(): from qulacs import ParametricQuantumCircuit from qulacs import QuantumState from qulacs import Observable from qulacs.gate import Probabilistic, X, Y, Z import numpy as np import matplotlib.pyplot as plt n_qubit = 2 p_list = [0.05, 0.1, 0.15] parametric_circuit_list = \ [ParametricQuantumCircuit(n_qubit) for i in range(len(p_list))] initial_state = QuantumState(n_qubit) for (p, circuit) in zip(p_list, parametric_circuit_list): circuit.add_H_gate(0) circuit.add_parametric_RY_gate(1, np.pi / 6) circuit.add_CNOT_gate(0, 1) prob = Probabilistic([p / 4, p / 4, p / 4], [X(0), Y(0), Z(0)]) circuit.add_gate(prob) noiseless_circuit = ParametricQuantumCircuit(n_qubit) noiseless_circuit.add_H_gate(0) noiseless_circuit.add_parametric_RY_gate(1, np.pi / 6) noiseless_circuit.add_CNOT_gate(0, 1) n_sample_per_circuit = 1 n_circuit_sample = 1000 obs = Observable(n_qubit) obs.add_operator(1.0, "Z 0 Z 1") obs.add_operator(0.5, "X 0 X 1") initial_param = np.array([np.pi / 6]) opt = VqeOptimizer(parametric_circuit_list, initial_state, obs, initial_param, p_list, n_circuit_sample=n_circuit_sample, n_sample_per_circuit=n_sample_per_circuit, noiseless_circuit=noiseless_circuit) noisy = opt.sample_output(initial_param) mitigated, exp_array, _ = opt.sample_mitigated_output(initial_param, return_full=True) exact = opt.exact_output(initial_param) print(noisy, exact) print(exp_array, mitigated) opt_param = opt.optimize() print(opt_param) theta_list = np.linspace(0, np.pi, 100) output_list = [opt.exact_output([theta]) for theta in theta_list] plt.plot(theta_list, output_list, color="black", linestyle="dashed", label="exact") plt.scatter(opt.parameter_history, opt.exp_history, c="blue", label="optimization history") plt.xlabel("theta") plt.ylabel("output") plt.legend() plt.show()
import numpy as np from functools import reduce from qulacs.gate import X, Y, Z, DenseMatrix I_mat = np.eye(2, dtype=complex) X_mat = X(0).get_matrix() Y_mat = Y(0).get_matrix() Z_mat = Z(0).get_matrix() ## Function to create full-size gate def make_fullgate(list_SiteAndOperator, nqubit): """ Receive list_SiteAndOperator = [ [i_0, O_0], [i_1, O_1], ...] Insert Identity to irrelevant qubtis Create (2**nqubit, 2**nqubit) martrix of I(0) * ... * O_0(i_0) * ... * O_1(i_1) ... """ list_Site = [SiteAndOperator[0] for SiteAndOperator in list_SiteAndOperator] list_SingleGates = [] ## reduce 1-qubit gates using np.kron cnt = 0 for i in range(nqubit): if i in list_Site: list_SingleGates.append( list_SiteAndOperator[cnt][1] ) cnt += 1 else: list_SingleGates.append(I_mat) return reduce(np.kron, list_SingleGates) def create_Ising_time_evol_gate(nqubit, time_step=0.77):
from qulacs import Observable from qulacs import QuantumState, QuantumCircuit from qulacs.gate import Probabilistic, X import matplotlib.pyplot as plt obs = Observable(1) obs.add_operator(1, "Z 0") state = QuantumState(1) circuit = QuantumCircuit(1) p = 0.1 # probability of bit flip n_circuit_sample = 10000 n_depth = 20 # the number of probabilistic gate probabilistic_pauli_gate = Probabilistic([p], [X(0)]) #define probabilistic gate circuit.add_gate(probabilistic_pauli_gate) # add the prob. gate to the circuit exp_array = [] for depth in range(n_depth): exp = 0 for i in [0] * n_circuit_sample: state.set_zero_state() for _ in range(depth): circuit.update_quantum_state(state) # apply the prob. gate exp += obs.get_expectation_value( state) # get expectation value for one sample of circuit exp /= n_circuit_sample # get overall average exp_array.append(exp)
m = 2**num_bits dist_mat = np.full((m, m), .5 / m) for x in range(m): dist_mat[x][x] = -1 + .5 / m if num_bits < 6: print("CU Gate Matrix:") for i in range(2**(num_bits + 1)): print(''.join([str(b) for b in cu_mat[i]])) print("Dist Gate Matrix:") for i in range(2**num_bits): print(''.join(["{:>6.2}".format(b) for b in dist_mat[i]])) state = QuantumState(num_bits + 1) state.set_computational_basis(0) x_gate = X(0) x_gate.update_quantum_state(state) print("\nInitial State:") show_quantum_state(state) for i in range(0, num_bits + 1): h_gate = H(i) h_gate.update_quantum_state(state) print("\nAfter H Gate:") show_quantum_state(state) ite = int(math.pow(2., num_bits * .5)) cu_gate = DenseMatrix(tuple(range(num_bits + 1)), cu_mat)
#### Preprare teacher data input_train = list() value_train = list() with open('Training.data', 'rb') as f: data = pickle.load(f) state = QuantumState(nqubit) for d in data: input_train.append(d[0]) value_train.append(d[1]) ## Basic gates I_mat = np.eye(2, dtype=complex) X_mat = X(0).get_matrix() Z_mat = Z(0).get_matrix() # Construct an output gate U_out and initialization. U_out = ParametricQuantumCircuit(nqubit) for d in range(c_depth): for i in range(nqubit): angle = 2.0 * np.pi * np.random.rand() U_out.add_parametric_RX_gate(i, angle) angle = 2.0 * np.pi * np.random.rand() U_out.add_parametric_RZ_gate(i, angle) angle = 2.0 * np.pi * np.random.rand() U_out.add_parametric_RX_gate(i, angle) meas0 = Measurement(0, 0) U_out.add_gate(meas0) meas1 = Measurement(1, 1)
from qulacs import QuantumState from qulacs import QuantumCircuit from qulacs import Observable from qulacs.gate import X n = 1 state = QuantumState(n) state.set_zero_state() index = 1 while True: x_gate = X(index) x_gate.update.quantum_state(state) # observable setting # observalable = Observable(n) # observable.add_operator(1.0, "Z 2") # value = observable.get_expectation_value(state) # print(value) # Assuming that this program takes of zero time to perform its n-th Pauli-X gate step, # this program allows a countably infinite number of algorithmic steps. # Thomson lamp is a hypothetical problem. # But,how about the result of measurement? # Is measurement available? After the completion of infinite steps...
def create_input_gate(self, x, uin_type): # Encode x into quantum state # uin_type: unitary data-input type 0, 1, 20, 21, 30, 31, 40, 41, 50, 51, 60, 61 # x = 1dim. variables, [-1,1] I_mat = np.eye(2, dtype=complex) X_mat = X(0).get_matrix() Y_mat = Y(0).get_matrix() Z_mat = Z(0).get_matrix() #make operators s.t. exp(i*theta * sigma^z_j@sigma^z_k) @:tensor product def ZZ(u, theta, j, k): u.add_CNOT_gate(j, k) u.add_RZ_gate(k, -2 * theta * self.time_step) u.add_CNOT_gate(j, k) return u def XX(u, theta, j, k): u.add_H_gate(j) u.add_H_gate(k) ZZ(u, theta, j, k) u.add_H_gate(j) u.add_H_gate(k) return u def YY(u, theta, j, k): u.add_U1_gate(j, -np.pi / 2.) u.add_U1_gate(k, -np.pi / 2.) XX(u, theta, j, k) u.add_U1_gate(j, np.pi / 2.) u.add_U1_gate(k, np.pi / 2.) return u theta = x u = QuantumCircuit(self.nqubit) angle_y = np.arcsin(x) angle_z = np.arccos(x**2) if uin_type == 0: for i in range(self.nqubit): u.add_RY_gate(i, angle_y[i]) u.add_RZ_gate(i, angle_z[i]) elif uin_type == 1: #for d in range(2): for i in range(self.nqubit): u.add_H_gate(i) u.add_RY_gate(i, angle_y[i]) u.add_RZ_gate(i, angle_z[i]) # KT: add second order expansion for i in range(self.nqubit - 1): for j in range(i + 1, self.nqubit): angle_z2 = np.arccos(x[i] * x[j]) u.add_CNOT_gate(i, j) u.add_RZ_gate(j, angle_z2) u.add_CNOT_gate(i, j) elif uin_type == 20: for i in range(self.nqubit): u.add_RX_gate(i, -2 * x[i] * self.time_step) elif uin_type == 21: ham = np.zeros((2**self.nqubit, 2**self.nqubit), dtype=complex) for i in range(self.nqubit): # i runs 0 to nqubit-1 J_x = x[i] print(x) ham += J_x * make_fullgate([[i, X_mat]], self.nqubit) ## Build time-evolution operator by diagonalizing the Ising hamiltonian H*P = P*D <-> H = P*D*P^dagger diag, eigen_vecs = np.linalg.eigh(ham) time_evol_op = np.dot( np.dot(eigen_vecs, np.diag(np.exp(-1j * self.time_step * diag))), eigen_vecs.T.conj()) # e^-iHT # Convert to qulacs gate time_evol_gate = DenseMatrix([i for i in range(self.nqubit)], time_evol_op) u.add_gate(time_evol_gate) elif uin_type == 30: #Ising hamiltonian with input coefficient # nearest neighbor spin-conbination has interaction for i in range(self.nqubit): u.add_RX_gate(i, -2 * x[i] * self.time_step) ZZ(u, theta[i] * theta[(i + 1) % self.nqubit], i, i + 1) elif uin_type == 31: ham = np.zeros((2**self.nqubit, 2**self.nqubit), dtype=complex) for i in range(self.nqubit): J_x = x[i] ham += J_x * make_fullgate([[i, X_mat]], self.nqubit) J_zz = x[i] * x[(i + 1) % self.nqubit] ham += J_zz * make_fullgate( [[i, Z_mat], [(i + 1) % self.nqubit, Z_mat]], self.nqubit) diag, eigen_vecs = np.linalg.eigh(ham) time_evol_op = np.dot( np.dot(eigen_vecs, np.diag(np.exp(-1j * self.time_step * diag))), eigen_vecs.T.conj()) time_evol_gate = DenseMatrix([i for i in range(self.nqubit)], time_evol_op) u.add_gate(time_evol_gate) elif uin_type == 40: #Ising hamiltonian with input coefficient # every two possible spin-conbination has interaction for i in range(self.nqubit): u.add_RX_gate(i, -2 * x[i] * self.time_step) for j in range(i + 1, self.nqubit): ZZ(u, theta[i] * theta[j], i, j) elif uin_type == 41: ham = np.zeros((2**self.nqubit, 2**self.nqubit), dtype=complex) for i in range(self.nqubit): J_x = x[i] ham += J_x * make_fullgate([[i, X_mat]], self.nqubit) for j in range(i + 1, self.nqubit): J_ij = x[i] * x[j] ham += J_ij * make_fullgate([[i, Z_mat], [j, Z_mat]], self.nqubit) diag, eigen_vecs = np.linalg.eigh(ham) time_evol_op = np.dot( np.dot(eigen_vecs, np.diag(np.exp(-1j * self.time_step * diag))), eigen_vecs.T.conj()) time_evol_gate = DenseMatrix([i for i in range(self.nqubit)], time_evol_op) u.add_gate(time_evol_gate) elif uin_type == 50: #Heisenberg hamiltonian with input coefficient # nearest neighbor spin-conbination has interaction for i in range(self.nqubit): u.add_RX_gate(i, -2 * x[i] * self.time_step) XX(u, theta[i] * theta[(i + 1) % self.nqubit], i, i + 1) YY(u, theta[i] * theta[(i + 1) % self.nqubit], i, i + 1) ZZ(u, theta[i] * theta[(i + 1) % self.nqubit], i, i + 1) elif uin_type == 51: ham = np.zeros((2**self.nqubit, 2**self.nqubit), dtype=complex) for i in range(self.nqubit): J_x = x[i] ham += J_x * make_fullgate([[i, X_mat]], self.nqubit) J_xx = x[i] * x[(i + 1) % self.nqubit] J_yy = x[i] * x[(i + 1) % self.nqubit] J_zz = x[i] * x[(i + 1) % self.nqubit] ham += J_xx * make_fullgate( [[i, X_mat], [(i + 1) % self.nqubit, X_mat]], self.nqubit) ham += J_yy * make_fullgate( [[i, Y_mat], [(i + 1) % self.nqubit, Y_mat]], self.nqubit) ham += J_xx * make_fullgate( [[i, Z_mat], [(i + 1) % self.nqubit, Z_mat]], self.nqubit) diag, eigen_vecs = np.linalg.eigh(ham) time_evol_op = np.dot( np.dot(eigen_vecs, np.diag(np.exp(-1j * self.time_step * diag))), eigen_vecs.T.conj()) time_evol_gate = DenseMatrix([i for i in range(self.nqubit)], time_evol_op) u.add_gate(time_evol_gate) elif uin_type == 60: #Heisenberg hamiltonian with input coefficient # every two possible spin-conbination has interaction for i in range(self.nqubit): u.add_RX_gate(i, -2 * x[i] * self.time_step) for j in range(i + 1, self.nqubit): XX(u, theta[i] * theta[j], i, j) YY(u, theta[i] * theta[j], i, j) ZZ(u, theta[i] * theta[j], i, j) elif uin_type == 61: ham = np.zeros((2**self.nqubit, 2**self.nqubit), dtype=complex) for i in range(self.nqubit): J_x = x[i] ham += J_x * make_fullgate([[i, X_mat]], self.nqubit) for j in range(i + 1, self.nqubit): J_xx = x[i] * x[j] J_yy = x[i] * x[j] J_zz = x[i] * x[j] ham += J_xx * make_fullgate([[i, X_mat], [j, X_mat]], self.nqubit) ham += J_yy * make_fullgate([[i, Y_mat], [j, Y_mat]], self.nqubit) ham += J_xx * make_fullgate([[i, Z_mat], [j, Z_mat]], self.nqubit) diag, eigen_vecs = np.linalg.eigh(ham) time_evol_op = np.dot( np.dot(eigen_vecs, np.diag(np.exp(-1j * self.time_step * diag))), eigen_vecs.T.conj()) time_evol_gate = DenseMatrix([i for i in range(self.nqubit)], time_evol_op) u.add_gate(time_evol_gate) else: pass return u