def test_Toffoli(benchmark, nqubits):
    benchmark.group = "Toffoli"
    toffoli = DenseMatrix(0, [[0, 1], [1, 0]])
    toffoli.add_control_qubit(1, 1)
    toffoli.add_control_qubit(2, 1)
    st = QuantumState(nqubits)
    benchmark(toffoli.update_quantum_state, st)
Example #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
Example #3
0
def prepstate(n_qubit, statevec):
    dim = 2**n_qubit

    if isinstance(statevec, dict):
        sv = np.zeros((dim, ), complex)
        for k, v in statevec.items():
            sv[k] = v
        statevec = sv

    matrix = np.zeros((dim, dim), complex)
    matrix[:, 0] = statevec

    from qulacs.gate import DenseMatrix
    from qulacs import QuantumState
    state = QuantumState(n_qubit)
    state.set_zero_state()
    gate = DenseMatrix(list(range(n_qubit)), matrix)
    gate.update_quantum_state(state)

    return state
Example #4
0
def create_Ising_time_evol_gate(nqubit, time_step=0.77):
    """ Ising hamiltonian with random magnetic field and random couplings
    :param time_step: elapsed time of random hamiltonian evolution
    :return  qulacs gate object
    """
    ham = np.zeros((2**nqubit,2**nqubit), dtype = complex)
    for i in range(nqubit):  # i runs 0 to nqubit-1
        Jx = -1. + 2.*np.random.rand()  # [-1,1]
        ham += Jx * make_fullgate( [ [i, X_mat] ], nqubit)
        for j in range(i+1, nqubit):
            J_ij = -1. + 2.*np.random.rand()
            ham += J_ij * make_fullgate ([ [i, Z_mat], [j, Z_mat]], 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*time_step*diag))), eigen_vecs.T.conj())  # e^-iHT

    # Convert to qulacs gate
    time_evol_gate = DenseMatrix([i for i in range(nqubit)], time_evol_op)

    return time_evol_gate
Example #5
0
def create_Heisenberg_time_evol_gate(nqubit, time_step=0.77):
    """ Heisenberg hamiltonian with random magnetic field and random couplings
    :param time_step: elapsed time of random hamiltonian evolution
    :return  qulacs gate object
    """
    # every two possible spin-conbination has interaction
    ham = np.zeros((2**nqubit, 2**nqubit), dtype = complex)
    for i in range(nqubit):
        J_x = -1. + 2. * np.random.rand()
        ham += J_x * make_fullgate([[i, X_mat]], nqubit)
        for j in range(i+1, nqubit):
            J_xx = -1. + 2. * np.random.rand()
            J_yy = -1. + 2. * np.random.rand()
            J_zz = -1. + 2. * np.random.rand()
            ham += J_xx * make_fullgate([[i, X_mat], [j, X_mat]], nqubit)
            ham += J_yy * make_fullgate([[i, Y_mat], [j, Y_mat]], nqubit)
            ham += J_xx * make_fullgate([[i, Z_mat], [j, Z_mat]], nqubit)
    '''
    # nearest neighbor spin-conbination has interaction
    ham = np.zeros((2**nqubit, 2**nqubit), dtype = complex)
    for i in range(nqubit):
        J_x = -1. + 2. * np.random.rand()
        ham += J_x * make_fullgate([[i, X_mat]], nqubit)
        
        J_xx = -1. + 2. * np.random.rand()
        J_yy = -1. + 2. * np.random.rand()
        J_zz = -1. + 2. * np.random.rand()
        ham += J_xx * make_fullgate([[i, X_mat], [(i+1) % nqubit, X_mat]], nqubit)#Periodic boundary condition
        ham += J_yy * make_fullgate([[i, Y_mat], [(i+1) % nqubit, Y_mat]], nqubit)
        ham += J_xx * make_fullgate([[i, Z_mat], [(i+1) % nqubit, Z_mat]], nqubit)
    '''
    
    ## Build time-evolution operator by diagonalizing the Heisenberg hamiltonian H*P = P*D <-> e^-iHt = P*(e^-iDt)*P^dagger
    diag, eigen_vecs = np.linalg.eigh(ham)
    time_evol_op = np.dot(np.dot(eigen_vecs, np.diag(np.exp(-1j*time_step*diag))), eigen_vecs.T.conj())  # e^-iHT

    # Convert to qulacs gate
    time_evol_gate = DenseMatrix([i for i in range(nqubit)], time_evol_op)

    return time_evol_gate
Example #6
0
def create_time_evol_gate(nqubit, time_step=0.77):
    """ ランダム磁場・ランダム結合イジングハミルトニアンをつくって時間発展演算子をつくる
    :param time_step: ランダムハミルトニアンによる時間発展の経過時間
    :return  qulacsのゲートオブジェクト
    """
    ham = np.zeros((2**nqubit, 2**nqubit), dtype=complex)
    for i in range(nqubit):  # i runs 0 to nqubit-1
        Jx = -1. + 2. * np.random.rand()  # -1~1の乱数
        ham += Jx * make_fullgate([[i, X_mat]], nqubit)
        for j in range(i + 1, nqubit):
            J_ij = -1. + 2. * np.random.rand()
            ham += J_ij * make_fullgate([[i, Z_mat], [j, Z_mat]], nqubit)

    # 対角化して時間発展演算子をつくる. 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 * time_step * diag))),
        eigen_vecs.T.conj())  # e^-iHT

    # qulacsのゲートに変換
    time_evol_gate = DenseMatrix([i for i in range(nqubit)], time_evol_op)

    return time_evol_gate
Example #7
0
def main():
    ## Example1
    circuit = QuantumCircuit(3)
    circuit.add_X_gate(0)
    circuit.add_Y_gate(1)
    circuit.add_Z_gate(2)
    circuit.add_dense_matrix_gate([0,1], [[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]])
    circuit.add_CNOT_gate(2,0)
    circuit.add_X_gate(2)
    draw_circuit(circuit, verbose=1)

    ## Example2
    circuit = QuantumCircuit(3)
    circuit.add_X_gate(0)
    circuit.add_Y_gate(1)
    circuit.add_dense_matrix_gate([0,1], [[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]])
    circuit.add_Z_gate(2)
    circuit.add_CNOT_gate(2,0)
    circuit.add_X_gate(2)
    draw_circuit(circuit, verbose=1)

    ## Example3
    circuit = QuantumCircuit(3)
    circuit.add_X_gate(1)
    circuit.add_CZ_gate(0,2)
    circuit.add_X_gate(1)
    draw_circuit(circuit)

    ## Example4
    circuit = QuantumCircuit(4)
    ##CCX0,2, 3
    cx_gate = CNOT(2,3)
    cx_mat_gate = to_matrix_gate(cx_gate)
    control_index = 0
    control_with_value = 1
    cx_mat_gate.add_control_qubit(control_index, control_with_value)
    circuit.add_gate(cx_mat_gate)
    ##CCX1,2, 3
    ccx = TOFFOLI(1,2, 3)
    circuit.add_gate(ccx)
    ##CCX1,2, 0
    ccx = TOFFOLI(1,2, 0)
    circuit.add_gate(ccx)
    ##CCX1,3, 0
    ccx = TOFFOLI(1,3, 0)
    circuit.add_gate(ccx)
    ##CCX1,3, 2
    ccx = TOFFOLI(1,3, 2)
    circuit.add_gate(ccx)
    ##SWAP0,1
    circuit.add_SWAP_gate(0,1)
    ##SWAP0,2
    circuit.add_SWAP_gate(0,2)
    ##SWAP1,3
    circuit.add_SWAP_gate(1,3)
    draw_circuit(circuit, verbose=1)

    ## Example5
    circuit = QuantumCircuit(5)
    ## 3-qubit gate applied to [0,1,2]
    mat = np.identity(2**3)
    circuit.add_dense_matrix_gate([0,1,2], mat)
    ## 3-qubit gate applied to [0,3,4], and [1] qubit is control-qubit
    c_dense_gate = DenseMatrix([0,3,4], mat)
    control_index = 1
    control_with_value = 1
    c_dense_gate.add_control_qubit(control_index, control_with_value)
    circuit.add_gate(c_dense_gate)
    ## 3-qubit gate applied to [0,2,4]
    circuit.add_dense_matrix_gate([0,2,4], mat)
    ## SWAP gate aplied to [1,3], and [2] qubit is control-qubit
    swp_gate = to_matrix_gate(SWAP(1,3))
    control_index = 2
    control_with_value = 1
    swp_gate.add_control_qubit(control_index, control_with_value)
    circuit.add_gate(swp_gate)
    draw_circuit(circuit)
Example #8
0
        print(''.join([str(b) for b in cu_mat[i]]))

state = QuantumState(num_bits + 1)
state.set_computational_basis(0)

print("\nInitial State:")
show_quantum_state(state)

for i in range(1, num_bits + 1):
    h_gate = H(i)
    h_gate.update_quantum_state(state)

print("\nAfter H Gate:")
show_quantum_state(state)

cu_gate = DenseMatrix(tuple(range(num_bits + 1)), cu_mat)
cu_gate.update_quantum_state(state)

print("\nAfter CU Gate:")
show_quantum_state(state)

z_gate = Z(0)
z_gate.update_quantum_state(state)

print("\nAfter Z Gate:")
show_quantum_state(state)

cu_gate = DenseMatrix(tuple(range(num_bits + 1)), cu_mat)
cu_gate.update_quantum_state(state)

print("\nAfter CU Gate:")
#### Operator for the time-evolution
ham = np.zeros((2**nqubit,2**nqubit), dtype = complex)
for i in range(nqubit): ## i runs 0 to nqubit-1
    Jx = -1. + 2.*np.random.rand() ## randm in -1~1
    ham += Jx * make_fullgate( [ [i, X_mat] ], nqubit)
    for j in range(i+1, nqubit):
        J_ij = -1. + 2.*np.random.rand()
        ham += J_ij * make_fullgate ([ [i, Z_mat], [j, Z_mat]], nqubit)

## Diagonize to make a time-evolution operator; 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*time_step*diag))), eigen_vecs.T.conj()) # e^-iHT

# Convert it to a qulacs gate
from qulacs.gate import DenseMatrix
time_evol_gate = DenseMatrix([i for i in range(nqubit)], time_evol_op)

from qulacs import ParametricQuantumCircuit

# Construct an output gate U_out and initialization.
U_out = ParametricQuantumCircuit(nqubit)
for d in range(c_depth):
    U_out.add_gate(time_evol_gate)
    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)
Example #10
0
def __get_CP(q0, q1, phase):

    exp = cmath.exp(1.j * phase)
    gate = DenseMatrix(q1, [[1., 0.], [0., exp]])
    gate.add_control_qubit(q0, 1)
    return gate
Example #11
0
def __get_P(q0, phase):

    exp = cmath.exp(1.j * phase)
    gate = DenseMatrix(q0, [[1., 0.], [0., exp]])
    return gate
Example #12
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