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()
Beispiel #2
0
    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
Beispiel #3
0
 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
Beispiel #4
0
 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
Beispiel #5
0
 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
Beispiel #6
0
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)
Beispiel #7
0
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()
Beispiel #8
0
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):
Beispiel #9
0
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)
Beispiel #10
0
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)
Beispiel #12
0
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...


Beispiel #13
0
    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