Exemplo n.º 1
0
 def testCSIGNtoCNOT(self):
     """
     CSIGN to CNOT: compare unitary matrix for CSIGN and product of
     resolved matrices in terms of CNOT.
     """
     qc1 = QubitCircuit(2)
     qc1.add_gate("CSIGN", targets=[1], controls=[0])
     U1 = gate_sequence_product(qc1.propagators())
     qc2 = qc1.resolve_gates(basis="CNOT")
     U2 = gate_sequence_product(qc2.propagators())
     assert_((U1 - U2).norm() < 1e-12)
Exemplo n.º 2
0
 def testCNOTtoSQRTSWAP(self):
     """
     CNOT to SQRTSWAP: compare unitary matrix for CNOT and product of
     resolved matrices in terms of SQRTSWAP.
     """
     qc1 = QubitCircuit(2)
     qc1.add_gate("CNOT", targets=[0], controls=[1])
     U1 = gate_sequence_product(qc1.propagators())
     qc2 = qc1.resolve_gates(basis="SQRTSWAP")
     U2 = gate_sequence_product(qc2.propagators())
     assert_((U1 - U2).norm() < 1e-12)
Exemplo n.º 3
0
 def testadjacentgates(self):
     """
     Adjacent Gates: compare unitary matrix for ISWAP and product of
     resolved matrices in terms of adjacent gates interaction.
     """
     qc1 = QubitCircuit(3)
     qc1.add_gate("ISWAP", targets=[0, 2])
     U1 = gate_sequence_product(qc1.propagators())
     qc0 = qc1.adjacent_gates()
     qc2 = qc0.resolve_gates(basis="ISWAP")
     U2 = gate_sequence_product(qc2.propagators())
     assert_((U1 - U2).norm() < 1e-12)
Exemplo n.º 4
0
    def test_linear_SQRTISWAP(self):
        """
        Linear Spin Chain Setup: compare unitary matrix for SQRTISWAP and
        propogator matrix of the implemented physical model.
        """
        N = 3

        qc = QubitCircuit(N)
        qc.add_gate("SQRTISWAP", targets=[0, 1])
        U_ideal = gate_sequence_product(qc.propagators())

        p = LinearSpinChain(N, correct_global_phase=True)
        U_list = p.run(qc)
        U_physical = gate_sequence_product(U_list)

        assert_((U_ideal - U_physical).norm() < 1e-12)
Exemplo n.º 5
0
    def skip_dispersivecqed_SQRTISWAP(self):
        """
        Dispersive cQED Setup: compare unitary matrix for SQRTISWAP and
        propogator matrix of the implemented physical model.
        """
        N = 3

        qc1 = QubitCircuit(N)
        qc1.add_gate("SQRTISWAP", targets=[0, 1])
        U_ideal = gate_sequence_product(qc1.propagators())

        p = DispersivecQED(N, correct_global_phase=True)
        U_list = p.run(qc1)
        U_physical = gate_sequence_product(U_list)

        print((U_ideal - U_physical).norm())
        assert_((U_ideal - U_physical).norm() < 1e-4)
Exemplo n.º 6
0
    def test_add_gate(self):
        """
        Addition of a gate object directly to a `QubitCircuit` 
        """
        qc = QubitCircuit(3)
        qc.add_gate("CNOT", targets=[1], controls=[0])
        test_gate = Gate("RZ", targets=[1], arg_value = 1.570796,
                         arg_label="P")
        qc.add_gate(test_gate)

        # Test explicit gate addition
        assert_(qc.gates[0].name == "CNOT")
        assert_(qc.gates[0].targets == [1])
        assert_(qc.gates[0].controls == [0])

        # Test direct gate addition
        assert_(qc.gates[1].name == test_gate.name)
        assert_(qc.gates[1].targets == test_gate.targets)
        assert_(qc.gates[1].controls == test_gate.controls)
Exemplo n.º 7
0
 def testCNOTtoISWAP(self):
     """
     CNOT to ISWAP: compare unitary matrix for CNOT and product of
     resolved matrices in terms of ISWAP.
     """
     qc1 = QubitCircuit(2)
     qc1.add_gate("CNOT", targets=[0], controls=[1])
     U1 = gate_sequence_product(qc1.propagators())
     qc2 = qc1.resolve_gates(basis="ISWAP")
     U2 = gate_sequence_product(qc2.propagators())
     assert_((U1 - U2).norm() < 1e-12)
Exemplo n.º 8
0
 def testISWAPtoCNOT(self):
     """
     ISWAP to CNOT: compare unitary matrix for ISWAP and product of
     resolved matrices in terms of CNOT.
     """
     qc1 = QubitCircuit(2)
     qc1.add_gate("ISWAP", targets=[0, 1])
     U1 = gate_sequence_product(qc1.propagators())
     qc2 = qc1.resolve_gates(basis="CNOT")
     U2 = gate_sequence_product(qc2.propagators())
     assert_((U1 - U2).norm() < 1e-12)
Exemplo n.º 9
0
 def testSNOTdecompose(self):
     """
     SNOT to rotation: compare unitary matrix for SNOT and product of
     resolved matrices in terms of rotation gates.
     """
     qc1 = QubitCircuit(1)
     qc1.add_gate("SNOT", targets=0)
     U1 = gate_sequence_product(qc1.propagators())
     qc2 = qc1.resolve_gates()
     U2 = gate_sequence_product(qc2.propagators())
     assert_((U1 - U2).norm() < 1e-12)
Exemplo n.º 10
0
 def testFREDKINdecompose(self):
     """
     FREDKIN to rotation and CNOT: compare unitary matrix for FREDKIN and product of
     resolved matrices in terms of rotation gates and CNOT.
     """
     qc1 = QubitCircuit(3)
     qc1.add_gate("FREDKIN", targets=[0, 1], controls=[2])
     U1 = gates.gate_sequence_product(qc1.propagators())
     qc2 = qc1.resolve_gates()
     U2 = gates.gate_sequence_product(qc2.propagators())
     assert _op_dist(U1, U2) < 1e-12
Exemplo n.º 11
0
def local(para, N):
    qc = QubitCircuit(N)
    shape = (N, 3)
    para = para.reshape(shape)
    i = 0
    for angles in para:
        qc.add_gate("RZ", i, None, angles[0])
        qc.add_gate("RX", i, None, angles[1])
        qc.add_gate("RZ", i, None, angles[2])
        i += 1
    return qc
Exemplo n.º 12
0
    def test_multi_gates(self):
        N = 2
        H_d = tensor([sigmaz()] * 2)
        H_c = []

        test = OptPulseProcessor(N)
        test.add_drift(H_d, [0, 1])
        test.add_control(sigmax(), cyclic_permutation=True)
        test.add_control(sigmay(), cyclic_permutation=True)
        test.add_control(tensor([sigmay(), sigmay()]))

        # qubits circuit with 3 gates
        setting_args = {
            "SNOT": {
                "num_tslots": 10,
                "evo_time": 1
            },
            "SWAP": {
                "num_tslots": 30,
                "evo_time": 3
            },
            "CNOT": {
                "num_tslots": 30,
                "evo_time": 3
            }
        }
        qc = QubitCircuit(N)
        qc.add_gate("SNOT", 0)
        qc.add_gate("SWAP", targets=[0, 1])
        qc.add_gate('CNOT', controls=1, targets=[0])
        test.load_circuit(qc, setting_args=setting_args, merge_gates=False)

        rho0 = rand_ket(4)  # use random generated ket state
        rho0.dims = [[2, 2], [1, 1]]
        U = gate_sequence_product(qc.propagators())
        rho1 = U * rho0
        result = test.run_state(rho0)
        assert_(fidelity(result.states[-1], rho1) > 1 - 1.0e-6)
Exemplo n.º 13
0
 def testadjacentgates(self):
     """
     Adjacent Gates: compare unitary matrix for ISWAP and product of
     resolved matrices in terms of adjacent gates interaction.
     """
     qc1 = QubitCircuit(3)
     qc1.add_gate("ISWAP", targets=[0, 2])
     U1 = gates.gate_sequence_product(qc1.propagators())
     qc0 = qc1.adjacent_gates()
     qc2 = qc0.resolve_gates(basis="ISWAP")
     U2 = gates.gate_sequence_product(qc2.propagators())
     assert _op_dist(U1, U2) < 1e-12
Exemplo n.º 14
0
    def test_linear_combination(self):
        """
        Linear Spin Chain Setup: compare unitary matrix for ISWAP, SQRTISWAP,
        RX and RY gates and the propogator matrix of the implemented physical
        model.
        """
        N = 3

        qc = QubitCircuit(N)
        qc.add_gate("ISWAP", targets=[0, 1])
        qc.add_gate("SQRTISWAP", targets=[0, 1])
        qc.add_gate("RZ", arg_value=np.pi/2, arg_label=r"\pi/2", targets=[1])
        qc.add_gate("RX", arg_value=np.pi/2, arg_label=r"\pi/2", targets=[0])
        U_ideal = gate_sequence_product(qc.propagators())

        p = LinearSpinChain(N, correct_global_phase=True)
        U_list = p.run(qc)
        U_physical = gate_sequence_product(U_list)

        assert_((U_ideal - U_physical).norm() < 1e-12)
Exemplo n.º 15
0
def qft_gate_sequence(N=1, swapping=True):
    """
    Quantum Fourier Transform operator on N qubits returning the gate sequence.
    
    Parameters
    ----------
    N: int
        Number of qubits.
    swap: boolean
        Flag indicating sequence of swap gates to be applied at the end or not.

    Returns
    -------
    qc: instance of QubitCircuit
        Gate sequence of Hadamard and controlled rotation gates implementing QFT
    
    """
    
    if N < 1:
        raise ValueError("Minimum value of N can be 1")

    qc = QubitCircuit(N)
    if N == 1:
        qc.add_gate("SNOT", targets=[0])
    else:
        for i in range(N):
            for j in range(i):
                qc.add_gate(r"CPHASE", targets=[j], controls=[i],
                            arg_label=r"{\pi/2^{%d}}" % (i - j),
                            arg_value=np.pi/(2**(i-j)))
            qc.add_gate("SNOT", targets=[i])
        if swapping == True:
            for i in range(N//2):
                qc.add_gate(r"SWAP", targets=[i], controls=[N-1-i])
        
    return qc
Exemplo n.º 16
0
def test_compiler_with_continous_pulse(spline_kind, schedule_mode):
    num_qubits = 2
    circuit = QubitCircuit(num_qubits)
    circuit.add_gate("X", targets=0)
    circuit.add_gate("X", targets=1)
    circuit.add_gate("X", targets=0)

    processor = CircularSpinChain(num_qubits)
    gauss_compiler = MyCompiler(
        processor.N, processor.params, processor.pulse_dict)
    processor.load_circuit(
        circuit, schedule_mode = schedule_mode, compiler=gauss_compiler)
    result = processor.run_state(init_state = basis([2,2], [0,0]))
    assert(abs(fidelity(result.states[-1],basis([2,2],[0,1])) - 1) < 1.e-6)
Exemplo n.º 17
0
    def test_user_gate(self):
        """
        User defined gate for QubitCircuit
        """
        def customer_gate1(arg_values):
            mat = np.zeros((4, 4), dtype=np.complex128)
            mat[0, 0] = mat[1, 1] = 1.
            mat[2:4, 2:4] = gates.rx(arg_values)
            return Qobj(mat, dims=[[2, 2], [2, 2]])

        def customer_gate2():
            mat = np.array([[1., 0], [0., 1.j]])
            return Qobj(mat, dims=[[2], [2]])

        qc = QubitCircuit(3)
        qc.user_gates = {"CTRLRX": customer_gate1, "T1": customer_gate2}
        qc.add_gate("CTRLRX", targets=[1, 2], arg_value=np.pi / 2)
        qc.add_gate("T1", targets=[1])
        props = qc.propagators()
        result1 = tensor(identity(2), customer_gate1(np.pi / 2))
        np.testing.assert_allclose(props[0], result1)
        result2 = tensor(identity(2), customer_gate2(), identity(2))
        np.testing.assert_allclose(props[1], result2)
Exemplo n.º 18
0
    def test_analytical_evo(self):
        """
        Test of run_state with exp(-iHt)
        """
        N = 3

        qc = QubitCircuit(N)
        qc.add_gate("ISWAP", targets=[0, 1])
        qc.add_gate("RZ", arg_value=np.pi / 2, arg_label=r"\pi/2", targets=[1])
        qc.add_gate("RX", arg_value=np.pi / 2, arg_label=r"\pi/2", targets=[0])
        U_ideal = gate_sequence_product(qc.propagators())

        rho0 = rand_ket(2**N)
        rho0.dims = [[2] * N, [1] * N]
        rho1 = gate_sequence_product([rho0] + qc.propagators())

        p = DispersivecQED(N, correct_global_phase=True)
        U_list = p.run_state(rho0=rho0, qc=qc, analytical=True)
        result = gate_sequence_product(U_list)
        assert_allclose(fidelity(result, rho1),
                        1.,
                        rtol=1e-2,
                        err_msg="Analytical run_state fails in DispersivecQED")
Exemplo n.º 19
0
    def test_dispersivecqed_combination(self):
        """
        Dispersive cQED Setup: compare unitary matrix for ISWAP, SQRTISWAP,
        RX and RY gates and the propogator matrix of the implemented physical
        model.
        """
        N = 3

        qc1 = QubitCircuit(N)
        qc1.add_gate("ISWAP", targets=[0, 1])
        qc1.add_gate("RZ", arg_value=np.pi/2, arg_label=r"\pi/2", targets=[1])
        qc1.add_gate("RX", arg_value=np.pi/2, arg_label=r"\pi/2", targets=[0])
        U_ideal = gate_sequence_product(qc1.propagators())

        p = DispersivecQED(N, correct_global_phase=True)
        U_list = p.run(qc1)
        U_physical = gate_sequence_product(U_list)

        print((U_ideal - U_physical).norm())
        assert_((U_ideal - U_physical).norm() < 1e-2)
Exemplo n.º 20
0
    def test_add_gate(self):
        """
        Addition of a gate object directly to a `QubitCircuit` 
        """
        qc = QubitCircuit(3)
        qc.add_gate("CNOT", targets=[1], controls=[0])
        test_gate = Gate("RZ", targets=[1], arg_value=1.570796, arg_label="P")
        qc.add_gate(test_gate)

        # Test explicit gate addition
        assert_(qc.gates[0].name == "CNOT")
        assert_(qc.gates[0].targets == [1])
        assert_(qc.gates[0].controls == [0])

        # Test direct gate addition
        assert_(qc.gates[1].name == test_gate.name)
        assert_(qc.gates[1].targets == test_gate.targets)
        assert_(qc.gates[1].controls == test_gate.controls)
Exemplo n.º 21
0
    def test_N_level_system(self):
        """
        Test for circuit with N-level system.
        """
        mat3 = rand_dm(3, density=1.)

        def controlled_mat3(arg_value):
            """
            A qubit control an operator acting on a 3 level system
            """
            control_value = arg_value
            dim = mat3.dims[0][0]
            return (tensor(fock_dm(2, control_value), mat3) +
                    tensor(fock_dm(2, 1 - control_value), identity(dim)))

        qc = QubitCircuit(2, dims=[3, 2])
        qc.user_gates = {"CTRLMAT3": controlled_mat3}
        qc.add_gate("CTRLMAT3", targets=[1, 0], arg_value=1)
        props = qc.propagators()
        np.testing.assert_allclose(mat3, ptrace(props[0], 0) - 1)
Exemplo n.º 22
0
def evolute(state):
    CNOT01 = Gate('CNOT', targets=1, controls=0)
    CNOT12 = Gate('CNOT', targets=2, controls=1)
    CNOT02 = Gate('CNOT', targets=2, controls=0)

    H0 = Gate('SNOT', targets=0)
    sqrtX0 = Gate('SQRTNOT', targets=0)
    H2 = Gate('SNOT', targets=2)

    qc = QubitCircuit(N=3)

    #     qc.add_gate(sqrtX0)
    #     qc.add_gate(sqrtX0)
    qc.add_gate(CNOT01)
    qc.add_gate(H0)

    #     qc.add_gate(CNOT12)
    #     qc.add_gate(H2)
    #     qc.add_gate(CNOT02)
    #     qc.add_gate(H2)

    gates_sequence = qc.propagators()
    scheme = oper.gate_sequence_product(gates_sequence)
    return scheme * state
Exemplo n.º 23
0
    def test_add_gate(self):
        """
        Addition of a gate object directly to a `QubitCircuit`
        """
        qc = QubitCircuit(6)
        qc.add_gate("CNOT", targets=[1], controls=[0])
        test_gate = Gate("SWAP", targets=[1, 4])
        qc.add_gate(test_gate)
        qc.add_gate("TOFFOLI", controls=[0, 1], targets=[2])
        qc.add_gate("SNOT", targets=[3])
        qc.add_gate(test_gate, index=[3])
        qc.add_1q_gate("RY", start=4, end=5, arg_value=1.570796)

        # Test explicit gate addition
        assert qc.gates[0].name == "CNOT"
        assert qc.gates[0].targets == [1]
        assert qc.gates[0].controls == [0]

        # Test direct gate addition
        assert qc.gates[1].name == test_gate.name
        assert qc.gates[1].targets == test_gate.targets

        # Test specified position gate addition
        assert qc.gates[3].name == test_gate.name
        assert qc.gates[3].targets == test_gate.targets

        # Test adding 1 qubit gate on [start, end] qubits
        assert qc.gates[5].name == "RY"
        assert qc.gates[5].targets == [4]
        assert qc.gates[5].arg_value == 1.570796
        assert qc.gates[6].name == "RY"
        assert qc.gates[6].targets == [5]
        assert qc.gates[5].arg_value == 1.570796

        # Test Exceptions  # Global phase is not included
        for gate in _single_qubit_gates:
            if gate not in _para_gates:
                # No target
                pytest.raises(ValueError, qc.add_gate, gate, None, None)
                # Multiple targets
                pytest.raises(ValueError, qc.add_gate, gate, [0, 1, 2], None)
                # With control
                pytest.raises(ValueError, qc.add_gate, gate, [0], [1])
            else:
                # No target
                pytest.raises(ValueError, qc.add_gate, gate, None, None, 1)
                # Multiple targets
                pytest.raises(ValueError, qc.add_gate, gate, [0, 1, 2], None, 1)
                # With control
                pytest.raises(ValueError, qc.add_gate, gate, [0], [1], 1)
        for gate in _ctrl_gates:
            if gate not in _para_gates:
                # No target
                pytest.raises(ValueError, qc.add_gate, gate, None, [1])
                # No control
                pytest.raises(ValueError, qc.add_gate, gate, [0], None)
            else:
                # No target
                pytest.raises(ValueError, qc.add_gate, gate, None, [1], 1)
                # No control
                pytest.raises(ValueError, qc.add_gate, gate, [0], None, 1)
        for gate in _swap_like:
            if gate not in _para_gates:
                # Single target
                pytest.raises(ValueError, qc.add_gate, gate, [0], None)
                # With control
                pytest.raises(ValueError, qc.add_gate, gate, [0, 1], [3])
            else:
                # Single target
                pytest.raises(ValueError, qc.add_gate, gate, [0], None, 1)
                # With control
                pytest.raises(ValueError, qc.add_gate, gate, [0, 1], [3], 1)
        for gate in _fredkin_like:
            # Single target
            pytest.raises(ValueError, qc.add_gate, gate, [0], [2])
            # No control
            pytest.raises(ValueError, qc.add_gate, gate, [0, 1], None)
        for gate in _toffoli_like:
            # No target
            pytest.raises(ValueError, qc.add_gate, gate, None, [1, 2])
            # Single control
            pytest.raises(ValueError, qc.add_gate, gate, [0], [1])
Exemplo n.º 24
0
    def test_reverse(self):
        """
        Reverse a quantum circuit
        """
        qc = QubitCircuit(3)

        qc.add_gate("RX", targets=[0], arg_value=3.141,
                    arg_label=r"\pi/2")
        qc.add_gate("CNOT", targets=[1], controls=[0])
        qc.add_gate("SNOT", targets=[2])
        # Keep input output same

        qc.add_state("0", targets=[0])
        qc.add_state("+", targets=[1], state_type="output")
        qc.add_state("-", targets=[1])

        qc.reverse_circuit()

        assert_(qc.gates[2].name == "SNOT")
        assert_(qc.gates[1].name == "CNOT")
        assert_(qc.gates[0].name == "RX")

        assert_(qc.input_states[0] == "0")
        assert_(qc.input_states[2] == None)
        assert_(qc.output_states[1] == "+")
Exemplo n.º 25
0
    def adjacent_gates(self, qc, setup="linear"):
        """
        Method to resolve 2 qubit gates with non-adjacent control/s or target/s
        in terms of gates with adjacent interactions for linear/circular spin
        chain system.

        Parameters
        ----------
        qc: :class:`.QubitCircuit`
            The circular spin chain circuit to be resolved

        setup: Boolean
            Linear of Circular spin chain setup

        Returns
        -------
        qc: :class:`.QubitCircuit`
            Returns QubitCircuit of resolved gates for the qubit circuit in the
            desired basis.
        """
        # FIXME This huge block has been here for a long time.
        # It could be moved to the new compiler section and carefully
        # splitted into smaller peaces.
        qc_t = QubitCircuit(qc.N, qc.reverse_states)
        swap_gates = ["SWAP", "ISWAP", "SQRTISWAP", "SQRTSWAP", "BERKELEY",
                      "SWAPalpha"]
        N = qc.N

        for gate in qc.gates:
            if gate.name == "CNOT" or gate.name == "CSIGN":
                start = min([gate.targets[0], gate.controls[0]])
                end = max([gate.targets[0], gate.controls[0]])

                if (setup == "linear" or
                        (setup == "circular" and (end - start) <= N // 2)):
                    i = start
                    while i < end:
                        if (start + end - i - i == 1 and
                                (end - start + 1) % 2 == 0):
                            # Apply required gate if control and target are
                            # adjacent to each other, provided |control-target|
                            # is even.
                            if end == gate.controls[0]:
                                qc_t.add_gate(gate.name, targets=[i],
                                              controls=[i + 1])
                            else:
                                qc_t.add_gate(gate.name, targets=[i + 1],
                                              controls=[i])

                        elif (start + end - i - i == 2 and
                              (end - start + 1) % 2 == 1):
                            # Apply a swap between i and its adjacent gate,
                            # then the required gate if and then another swap
                            # if control and target have one qubit between
                            # them, provided |control-target| is odd.
                            qc_t.add_gate("SWAP", targets=[i, i + 1])
                            if end == gate.controls[0]:
                                qc_t.add_gate(gate.name, targets=[i + 1],
                                              controls=[i + 2])
                            else:
                                qc_t.add_gate(gate.name, targets=[i + 2],
                                              controls=[i + 1])
                            qc_t.add_gate("SWAP", [i, i + 1])
                            i += 1

                        else:
                            # Swap the target/s and/or control with their
                            # adjacent qubit to bring them closer.
                            qc_t.add_gate("SWAP", [i, i + 1])
                            qc_t.add_gate("SWAP", [start + end - i - 1,
                                                   start + end - i])
                        i += 1

                elif (end - start) < N - 1:
                    """
                    If the resolving has to go backwards, the path is first
                    mapped to a separate circuit and then copied back to the
                    original circuit.
                    """

                    temp = QubitCircuit(N - end + start)
                    i = 0
                    while i < (N - end + start):

                        if (N + start - end - i - i == 1 and
                                (N - end + start + 1) % 2 == 0):
                            if end == gate.controls[0]:
                                temp.add_gate(gate.name, targets=[i],
                                              controls=[i + 1])
                            else:
                                temp.add_gate(gate.name, targets=[i + 1],
                                              controls=[i])

                        elif (N + start - end - i - i == 2 and
                              (N - end + start + 1) % 2 == 1):
                            temp.add_gate("SWAP", targets=[i, i + 1])
                            if end == gate.controls[0]:
                                temp.add_gate(gate.name, targets=[i + 2],
                                              controls=[i + 1])
                            else:
                                temp.add_gate(gate.name, targets=[i + 1],
                                              controls=[i + 2])
                            temp.add_gate("SWAP", [i, i + 1])
                            i += 1

                        else:
                            temp.add_gate("SWAP", [i, i + 1])
                            temp.add_gate("SWAP",
                                          [N + start - end - i - 1,
                                           N + start - end - i])
                        i += 1

                    j = 0
                    for gate in temp.gates:
                        if (j < N - end - 2):
                            if gate.name in ["CNOT", "CSIGN"]:
                                qc_t.add_gate(gate.name, end + gate.targets[0],
                                              end + gate.controls[0])
                            else:
                                qc_t.add_gate(gate.name,
                                              [end + gate.targets[0],
                                               end + gate.targets[1]])
                        elif (j == N - end - 2):
                            if gate.name in ["CNOT", "CSIGN"]:
                                qc_t.add_gate(gate.name, end + gate.targets[0],
                                              (end + gate.controls[0]) % N)
                            else:
                                qc_t.add_gate(gate.name,
                                              [end + gate.targets[0],
                                               (end + gate.targets[1]) % N])
                        else:
                            if gate.name in ["CNOT", "CSIGN"]:
                                qc_t.add_gate(gate.name,
                                              (end + gate.targets[0]) % N,
                                              (end + gate.controls[0]) % N)
                            else:
                                qc_t.add_gate(gate.name,
                                              [(end + gate.targets[0]) % N,
                                               (end + gate.targets[1]) % N])
                        j = j + 1

                elif (end - start) == N - 1:
                    qc_t.add_gate(gate.name, gate.targets, gate.controls)

            elif gate.name in swap_gates:
                start = min([gate.targets[0], gate.targets[1]])
                end = max([gate.targets[0], gate.targets[1]])

                if (setup == "linear" or
                        (setup == "circular" and (end - start) <= N // 2)):
                    i = start
                    while i < end:
                        if (start + end - i - i == 1 and
                                (end - start + 1) % 2 == 0):
                            qc_t.add_gate(gate.name, [i, i + 1])
                        elif ((start + end - i - i) == 2 and
                              (end - start + 1) % 2 == 1):
                            qc_t.add_gate("SWAP", [i, i + 1])
                            qc_t.add_gate(gate.name, [i + 1, i + 2])
                            qc_t.add_gate("SWAP", [i, i + 1])
                            i += 1
                        else:
                            qc_t.add_gate("SWAP", [i, i + 1])
                            qc_t.add_gate("SWAP", [start + end - i - 1,
                                                   start + end - i])
                        i += 1

                else:
                    temp = QubitCircuit(N - end + start)
                    i = 0
                    while i < (N - end + start):

                        if (N + start - end - i - i == 1 and
                                (N - end + start + 1) % 2 == 0):
                            temp.add_gate(gate.name, [i, i + 1])

                        elif (N + start - end - i - i == 2 and
                              (N - end + start + 1) % 2 == 1):
                            temp.add_gate("SWAP", [i, i + 1])
                            temp.add_gate(gate.name, [i + 1, i + 2])
                            temp.add_gate("SWAP", [i, i + 1])
                            i += 1

                        else:
                            temp.add_gate("SWAP", [i, i + 1])
                            temp.add_gate("SWAP", [N + start - end - i - 1,
                                                   N + start - end - i])
                        i += 1

                    j = 0
                    for gate in temp.gates:
                        if(j < N - end - 2):
                            qc_t.add_gate(gate.name, [end + gate.targets[0],
                                                      end + gate.targets[1]])
                        elif(j == N - end - 2):
                            qc_t.add_gate(gate.name,
                                          [end + gate.targets[0],
                                           (end + gate.targets[1]) % N])
                        else:
                            qc_t.add_gate(gate.name,
                                          [(end + gate.targets[0]) % N,
                                           (end + gate.targets[1]) % N])
                        j = j + 1

            else:
                qc_t.add_gate(gate.name, gate.targets, gate.controls,
                              gate.arg_value, gate.arg_label)

        return qc_t
Exemplo n.º 26
0
    def test_single_qubit_gates(self):
        """
        Text single qubit gates are added correctly
        """
        qc = QubitCircuit(3)

        qc.add_gate("X", targets=[0])
        qc.add_gate("CY", targets=[1], controls=[0])
        qc.add_gate("Y", targets=[2])
        qc.add_gate("CS", targets=[0], controls=[1])
        qc.add_gate("Z", targets=[1])
        qc.add_gate("CT", targets=[2], controls=[2])
        qc.add_gate("CZ", targets=[0], controls=[0])
        qc.add_gate("S", targets=[1])
        qc.add_gate("T", targets=[2])

        assert qc.gates[8].name == "T"
        assert qc.gates[7].name == "S"
        assert qc.gates[6].name == "CZ"
        assert qc.gates[5].name == "CT"
        assert qc.gates[4].name == "Z"
        assert qc.gates[3].name == "CS"
        assert qc.gates[2].name == "Y"
        assert qc.gates[1].name == "CY"
        assert qc.gates[0].name == "X"

        assert qc.gates[8].targets == [2]
        assert qc.gates[7].targets == [1]
        assert qc.gates[6].targets == [0]
        assert qc.gates[5].targets == [2]
        assert qc.gates[4].targets == [1]
        assert qc.gates[3].targets == [0]
        assert qc.gates[2].targets == [2]
        assert qc.gates[1].targets == [1]
        assert qc.gates[0].targets == [0]

        assert qc.gates[6].controls == [0]
        assert qc.gates[5].controls == [2]
        assert qc.gates[3].controls == [1]
        assert qc.gates[1].controls == [0]
Exemplo n.º 27
0
    def test_add_measurement(self):
        """
        Addition of Measurement Object to a circuit.
        """

        qc = QubitCircuit(3, num_cbits=2)

        qc.add_measurement("M0", targets=[0], classical_store=1)
        qc.add_gate("CNOT", targets=[1], controls=[0])
        qc.add_gate("TOFFOLI", controls=[0, 1], targets=[2])
        qc.add_measurement("M1", targets=[2], classical_store=0)
        qc.add_gate("SNOT", targets=[1], classical_controls=[0, 1])
        qc.add_measurement("M2", targets=[1])

        # checking correct addition of measurements
        assert qc.gates[0].targets[0] == 0
        assert qc.gates[0].classical_store == 1
        assert qc.gates[3].name == "M1"
        assert qc.gates[5].classical_store is None

        # checking if gates are added correctly with measurements
        assert qc.gates[2].name == "TOFFOLI"
        assert qc.gates[4].classical_controls == [0, 1]
Exemplo n.º 28
0
from qutip import *
from qutip.qip.circuit import QubitCircuit
from diamond.DiamondCircuit import save_circuit
import numpy as np

qc = QubitCircuit(4, reverse_states=False)
qc.add_gate('X', 0)
qc.add_gate('X', 1)
qc.add_gate('R_z', 2, [0, 1, 3], 0, r'\mp \frac{\pi}{2}')
qc.add_gate('R_y', 2, [0, 1, 3], 0, r'a')
qc.add_gate('R_z', 2, [0, 1, 3], 0, r'b')
qc.add_gate('A', [0, 1, 2, 3])
qc.add_gate('R_z', 2, [0, 1, 3], 0, r'\mp \frac{\pi}{2}')
qc.add_gate('R_y', 2, [0, 1, 3], 0, r'a')
qc.add_gate('R_z', 2, [0, 1, 3], 0, r'c')
qc.add_gate('B', [0, 1, 2, 3])
qc.add_gate('R_z', 3, [0, 1, 2], 0, r'\pm \frac{\pi}{2}')
qc.add_gate('R_y', 3, [0, 1, 2], 0, r'a')
qc.add_gate('R_z', 3, [0, 1, 2], 0, r'-b')
qc.add_gate('C', [0, 1, 2, 3])
qc.add_gate('R_z', 1, [0, 2, 3], 0, r'\pm \frac{\pi}{2}')
qc.add_gate('R_y', 1, [0, 2, 3], 0, r'a')
qc.add_gate('R_z', 1, [0, 2, 3], 0, r'-c')
qc.add_gate('D', [0, 1, 2, 3])
qc.add_gate('R_z', 3, [0, 1, 2], 0, r'\mp a')
qc.add_gate('R_y', 3, [0, 1, 2], 0, r'-\pi')
qc.add_gate('R_z', 3, [0, 1, 2], 0, r'\pm a')
qc.add_gate(r'R_{\phi}', 3, [0, 1, 2], 0, r't - \pi')
qc.add_gate('X', 1)
qc.add_gate('X', 2)
save_circuit(qc, 'U')
Exemplo n.º 29
0
    def adjacent_gates(self, qc, setup="linear"):
        """
        Method to resolve 2 qubit gates with non-adjacent control/s or target/s
        in terms of gates with adjacent interactions for linear/circular spin
        chain system.

        Parameters
        ----------
        qc: QubitCircuit
            The circular spin chain circuit to be resolved

        setup: Boolean
            Linear of Circular spin chain setup

        Returns
        ----------
        qc: QubitCircuit
            Returns QubitCircuit of resolved gates for the qubit circuit in the
            desired basis.
        """
        qc_t = QubitCircuit(qc.N, qc.reverse_states)
        swap_gates = ["SWAP", "ISWAP", "SQRTISWAP", "SQRTSWAP", "BERKELEY",
                      "SWAPalpha"]
        N = qc.N

        for gate in qc.gates:
            if gate.name == "CNOT" or gate.name == "CSIGN":
                start = min([gate.targets[0], gate.controls[0]])
                end = max([gate.targets[0], gate.controls[0]])

                if (setup == "linear" or
                        (setup == "circular" and (end - start) <= N // 2)):
                    i = start
                    while i < end:
                        if (start + end - i - i == 1 and
                                (end - start + 1) % 2 == 0):
                            # Apply required gate if control and target are
                            # adjacent to each other, provided |control-target|
                            # is even.
                            if end == gate.controls[0]:
                                qc_t.add_gate(gate.name, targets=[i],
                                              controls=[i + 1])
                            else:
                                qc_t.add_gate(gate.name, targets=[i + 1],
                                              controls=[i])

                        elif (start + end - i - i == 2 and
                              (end - start + 1) % 2 == 1):
                            # Apply a swap between i and its adjacent gate,
                            # then the required gate if and then another swap
                            # if control and target have one qubit between
                            # them, provided |control-target| is odd.
                            qc_t.add_gate("SWAP", targets=[i, i + 1])
                            if end == gate.controls[0]:
                                qc_t.add_gate(gate.name, targets=[i + 1],
                                              controls=[i + 2])
                            else:
                                qc_t.add_gate(gate.name, targets=[i + 2],
                                              controls=[i + 1])
                            qc_t.add_gate("SWAP", [i, i + 1])
                            i += 1

                        else:
                            # Swap the target/s and/or control with their
                            # adjacent qubit to bring them closer.
                            qc_t.add_gate("SWAP", [i, i + 1])
                            qc_t.add_gate("SWAP", [start + end - i - 1,
                                                   start + end - i])
                        i += 1

                elif (end - start) < N - 1:
                    """
                    If the resolving has to go backwards, the path is first
                    mapped to a separate circuit and then copied back to the
                    original circuit.
                    """

                    temp = QubitCircuit(N - end + start)
                    i = 0
                    while i < (N - end + start):

                        if (N + start - end - i - i == 1 and
                                (N - end + start + 1) % 2 == 0):
                            if end == gate.controls[0]:
                                temp.add_gate(gate.name, targets=[i],
                                              controls=[i + 1])
                            else:
                                temp.add_gate(gate.name, targets=[i + 1],
                                              controls=[i])

                        elif (N + start - end - i - i == 2 and
                              (N - end + start + 1) % 2 == 1):
                            temp.add_gate("SWAP", targets=[i, i + 1])
                            if end == gate.controls[0]:
                                temp.add_gate(gate.name, targets=[i + 2],
                                              controls=[i + 1])
                            else:
                                temp.add_gate(gate.name, targets=[i + 1],
                                              controls=[i + 2])
                            temp.add_gate("SWAP", [i, i + 1])
                            i += 1

                        else:
                            temp.add_gate("SWAP", [i, i + 1])
                            temp.add_gate("SWAP",
                                          [N + start - end - i - 1,
                                           N + start - end - i])
                        i += 1

                    j = 0
                    for gate in temp.gates:
                        if (j < N - end - 2):
                            if gate.name in ["CNOT", "CSIGN"]:
                                qc_t.add_gate(gate.name, end + gate.targets[0],
                                              end + gate.controls[0])
                            else:
                                qc_t.add_gate(gate.name,
                                              [end + gate.targets[0],
                                               end + gate.targets[1]])
                        elif (j == N - end - 2):
                            if gate.name in ["CNOT", "CSIGN"]:
                                qc_t.add_gate(gate.name, end + gate.targets[0],
                                              (end + gate.controls[0]) % N)
                            else:
                                qc_t.add_gate(gate.name,
                                              [end + gate.targets[0],
                                               (end + gate.targets[1]) % N])
                        else:
                            if gate.name in ["CNOT", "CSIGN"]:
                                qc_t.add_gate(gate.name,
                                              (end + gate.targets[0]) % N,
                                              (end + gate.controls[0]) % N)
                            else:
                                qc_t.add_gate(gate.name,
                                              [(end + gate.targets[0]) % N,
                                               (end + gate.targets[1]) % N])
                        j = j + 1

                elif (end - start) == N - 1:
                    qc_t.add_gate(gate.name, gate.targets, gate.controls)

            elif gate.name in swap_gates:
                start = min([gate.targets[0], gate.targets[1]])
                end = max([gate.targets[0], gate.targets[1]])

                if (setup == "linear" or
                        (setup == "circular" and (end - start) <= N // 2)):
                    i = start
                    while i < end:
                        if (start + end - i - i == 1 and
                                (end - start + 1) % 2 == 0):
                            qc_t.add_gate(gate.name, [i, i + 1])
                        elif ((start + end - i - i) == 2 and
                              (end - start + 1) % 2 == 1):
                            qc_t.add_gate("SWAP", [i, i + 1])
                            qc_t.add_gate(gate.name, [i + 1, i + 2])
                            qc_t.add_gate("SWAP", [i, i + 1])
                            i += 1
                        else:
                            qc_t.add_gate("SWAP", [i, i + 1])
                            qc_t.add_gate("SWAP", [start + end - i - 1,
                                                   start + end - i])
                        i += 1

                else:
                    temp = QubitCircuit(N - end + start)
                    i = 0
                    while i < (N - end + start):

                        if (N + start - end - i - i == 1 and
                                (N - end + start + 1) % 2 == 0):
                            temp.add_gate(gate.name, [i, i + 1])

                        elif (N + start - end - i - i == 2 and
                              (N - end + start + 1) % 2 == 1):
                            temp.add_gate("SWAP", [i, i + 1])
                            temp.add_gate(gate.name, [i + 1, i + 2])
                            temp.add_gate("SWAP", [i, i + 1])
                            i += 1

                        else:
                            temp.add_gate("SWAP", [i, i + 1])
                            temp.add_gate("SWAP", [N + start - end - i - 1,
                                                   N + start - end - i])
                        i += 1

                    j = 0
                    for gate in temp.gates:
                        if(j < N - end - 2):
                            qc_t.add_gate(gate.name, [end + gate.targets[0],
                                                      end + gate.targets[1]])
                        elif(j == N - end - 2):
                            qc_t.add_gate(gate.name,
                                          [end + gate.targets[0],
                                           (end + gate.targets[1]) % N])
                        else:
                            qc_t.add_gate(gate.name,
                                          [(end + gate.targets[0]) % N,
                                           (end + gate.targets[1]) % N])
                        j = j + 1

            else:
                qc_t.add_gate(gate.name, gate.targets, gate.controls,
                              gate.arg_value, gate.arg_label)

        return qc_t
Exemplo n.º 30
0
    def test_add_circuit(self):
        """
        Addition of a circuit to a `QubitCircuit`
        """
        qc = QubitCircuit(6)
        qc.add_gate("CNOT", targets=[1], controls=[0])
        test_gate = Gate("SWAP", targets=[1, 4])
        qc.add_gate(test_gate)
        qc.add_gate("TOFFOLI", controls=[0, 1], targets=[2])
        qc.add_gate("SNOT", targets=[3])
        qc.add_gate(test_gate, index=[3])
        qc.add_measurement("M0", targets=[0], classical_store=[1])
        qc.add_1q_gate("RY", start=4, end=5, arg_value=1.570796)

        qc1 = QubitCircuit(6)

        qc1.add_circuit(qc)

        # Test if all gates and measurements are added
        assert len(qc1.gates) == len(qc.gates)

        for i in range(len(qc1.gates)):
            assert (qc1.gates[i].name
                    == qc.gates[i].name)
            assert (qc1.gates[i].targets
                    == qc.gates[i].targets)
            if (isinstance(qc1.gates[i], Gate) and
                    isinstance(qc.gates[i], Gate)):
                assert (qc1.gates[i].controls
                        == qc.gates[i].controls)
                assert (qc1.gates[i].classical_controls
                        == qc.gates[i].classical_controls)
            elif (isinstance(qc1.gates[i], Measurement) and
                    isinstance(qc.gates[i], Measurement)):
                assert (qc1.gates[i].classical_store
                        == qc.gates[i].classical_store)

        # Test exception when qubit out of range
        pytest.raises(NotImplementedError, qc1.add_circuit, qc, start=4)

        qc2 = QubitCircuit(8)
        qc2.add_circuit(qc, start=2)

        # Test if all gates are added
        assert len(qc2.gates) == len(qc.gates)

        # Test if the positions are correct
        for i in range(len(qc2.gates)):
            if qc.gates[i].targets is not None:
                assert (qc2.gates[i].targets[0]
                        == qc.gates[i].targets[0]+2)
            if (isinstance(qc.gates[i], Gate) and
                    qc.gates[i].controls is not None):
                assert (qc2.gates[i].controls[0]
                        == qc.gates[i].controls[0]+2)
Exemplo n.º 31
0
 def testStateParams(a1, a2, a3, a4, a5, a6):
     QC = QubitCircuit(3)
     QC.add_gate("RX", targets=0, arg_value=a1)
     QC.add_gate("RX", targets=1, arg_value=a2)
     QC.add_gate("RX", targets=2, arg_value=a3)
     QC.add_gate("CNOT", targets=1, controls=0)
     QC.add_gate("CNOT", targets=2, controls=0)
     QC.add_gate("RX", targets=0, arg_value=a4)
     QC.add_gate("RX", targets=1, arg_value=a5)
     QC.add_gate("RX", targets=2, arg_value=a6)
     U_list = QC.propagators()
     finalGate = gate_sequence_product(U_list)
     finalState = finalGate * initialState
     return calcStateFidelity(targetState, finalState)
Exemplo n.º 32
0
    def test_add_state(self):
        """
        Addition of input and output states to a circuit.
        """
        qc = QubitCircuit(3)

        qc.add_state("0", targets=[0])
        qc.add_state("+", targets=[1], state_type="output")
        qc.add_state("-", targets=[1])

        assert qc.input_states[0] == "0"
        assert qc.input_states[2] is None
        assert qc.output_states[1] == "+"

        qc1 = QubitCircuit(10)

        qc1.add_state("0", targets=[2, 3, 5, 6])
        qc1.add_state("+", targets=[1, 4, 9])
        qc1.add_state("A", targets=[1, 4, 9], state_type="output")
        qc1.add_state("A", targets=[1, 4, 9], state_type="output")
        qc1.add_state("beta", targets=[0], state_type="output")
        assert qc1.input_states[0] is None

        assert qc1.input_states[2] == "0"
        assert qc1.input_states[3] == "0"
        assert qc1.input_states[6] == "0"
        assert qc1.input_states[1] == "+"
        assert qc1.input_states[4] == "+"

        assert qc1.output_states[2] is None
        assert qc1.output_states[1] == "A"
        assert qc1.output_states[4] == "A"
        assert qc1.output_states[9] == "A"

        assert qc1.output_states[0] == "beta"
Exemplo n.º 33
0
from .three_q_generators import *
from numpy import pi
from qutip.qip.operations import snot
from qutip.qip.circuit import QubitCircuit
from qutip.qip.operations import gate_sequence_product
from qutip.tensor import tensor
import qutip as qt

spins = []

for i in range(1, 4):
    spins.append(qt.basis(2, 0))

initial_state = tensor(spins)

QC = QubitCircuit(3)
QC.add_gate("RX", targets=0, arg_value=0.5)
QC.add_gate("RX", targets=1, arg_value=0.1)
QC.add_gate("RX", targets=2, arg_value=0.2223472)
QC.add_gate("CNOT", targets=1, controls=0)
QC.add_gate("CNOT", targets=2, controls=0)
QC.add_gate("RX", targets=0, arg_value=0.26127)
QC.add_gate("RX", targets=1, arg_value=1.3942948)
QC.add_gate("RX", targets=1, arg_value=0.4378)
U_list = QC.propagators()

TargetGate = gate_sequence_product(U_list)


class threeQubitCircuit(problem):
    def __init__(self,
Exemplo n.º 34
0
 def test_exceptions(self, gate):
     """
     Text exceptions are thrown correctly for inadequate inputs
     """
     qc = QubitCircuit(2)
     pytest.raises(ValueError, qc.add_gate, gate, targets=[1], controls=[0])
Exemplo n.º 35
0
def _circuit1():
    circuit1 = QubitCircuit(6)
    circuit1.add_gate("SNOT", 2)
    circuit1.add_gate("CNOT", 4, 2)
    circuit1.add_gate("CNOT", 3, 2)
    circuit1.add_gate("CNOT", 1, 2)
    circuit1.add_gate("CNOT", 5, 4)
    circuit1.add_gate("CNOT", 1, 5)
    circuit1.add_gate("SWAP", [0, 1])
    return circuit1
Exemplo n.º 36
0
    def test_reverse(self):
        """
        Reverse a quantum circuit
        """
        qc = QubitCircuit(3)

        qc.add_gate("RX", targets=[0], arg_value=3.141,
                    arg_label=r"\pi/2")
        qc.add_gate("CNOT", targets=[1], controls=[0])
        qc.add_measurement("M1", targets=[1])
        qc.add_gate("SNOT", targets=[2])
        # Keep input output same

        qc.add_state("0", targets=[0])
        qc.add_state("+", targets=[1], state_type="output")
        qc.add_state("-", targets=[1])

        qc_rev = qc.reverse_circuit()

        assert qc_rev.gates[0].name == "SNOT"
        assert qc_rev.gates[1].name == "M1"
        assert qc_rev.gates[2].name == "CNOT"
        assert qc_rev.gates[3].name == "RX"

        assert qc_rev.input_states[0] == "0"
        assert qc_rev.input_states[2] is None
        assert qc_rev.output_states[1] == "+"
Exemplo n.º 37
0
def _circuit2():
    circuit2 = QubitCircuit(8)
    circuit2.add_gate("SNOT", 1)
    circuit2.add_gate("SNOT", 2)
    circuit2.add_gate("SNOT", 3)
    circuit2.add_gate("CNOT", 4, 5)
    circuit2.add_gate("CNOT", 4, 6)
    circuit2.add_gate("CNOT", 3, 4)
    circuit2.add_gate("CNOT", 3, 5)
    circuit2.add_gate("CNOT", 3, 7)
    circuit2.add_gate("CNOT", 2, 4)
    circuit2.add_gate("CNOT", 2, 6)
    circuit2.add_gate("CNOT", 2, 7)
    circuit2.add_gate("CNOT", 1, 5)
    circuit2.add_gate("CNOT", 1, 6)
    circuit2.add_gate("CNOT", 1, 7)
    return circuit2
Exemplo n.º 38
0
def _teleportation_circuit():
    teleportation = QubitCircuit(3, num_cbits=2,
                                input_states=["q0", "0", "0", "c0", "c1"])

    teleportation.add_gate("SNOT", targets=[1])
    teleportation.add_gate("CNOT", targets=[2], controls=[1])
    teleportation.add_gate("CNOT", targets=[1], controls=[0])
    teleportation.add_gate("SNOT", targets=[0])
    teleportation.add_measurement("M0", targets=[0], classical_store=1)
    teleportation.add_measurement("M1", targets=[1], classical_store=0)
    teleportation.add_gate("X", targets=[2], classical_controls=[0])
    teleportation.add_gate("Z", targets=[2], classical_controls=[1])

    return teleportation
Exemplo n.º 39
0
def _instructions1():
    circuit3 = QubitCircuit(6)
    circuit3.add_gate("SNOT", 0)
    circuit3.add_gate("SNOT", 1)
    circuit3.add_gate("CNOT", 2, 3)
    circuit3.add_gate("CNOT", 1, 2)
    circuit3.add_gate("CNOT", 1, 0)
    circuit3.add_gate("SNOT", 3)
    circuit3.add_gate("CNOT", 1, 3)
    circuit3.add_gate("CNOT", 1, 3)

    instruction_list = []
    for gate in circuit3.gates:
        if gate.name == "SNOT":
            instruction_list.append(Instruction(gate, duration=1))
        else:
            instruction_list.append(Instruction(gate, duration=2))

    return instruction_list
Exemplo n.º 40
0
def evolute(state):
    qc = QubitCircuit(N=3)
    qc.add_gate("CNOT", controls=0, targets=1)
    qc.add_gate("SNOT", targets=0)
    U_list = qc.propagators()
    return gate_sequence_product(U_list) * state
Exemplo n.º 41
0
    def test_add_state(self):
        """
        Addition of input and output states to a circuit.
        """
        qc = QubitCircuit(3)

        qc.add_state("0", targets=[0])
        qc.add_state("+", targets=[1], state_type="output")
        qc.add_state("-", targets=[1])

        assert_(qc.input_states[0] == "0")
        assert_(qc.input_states[2] == None)
        assert_(qc.output_states[1] == "+")

        qc1 = QubitCircuit(10)

        qc1.add_state("0", targets=[2, 3, 5, 6])
        qc1.add_state("+", targets=[1,4,9])
        qc1.add_state("A", targets=[1,4,9], state_type="output")
        qc1.add_state("A", targets=[1,4,9], state_type="output")
        qc1.add_state("beta", targets=[0], state_type="output")
        assert_(qc1.input_states[0] == None)
        
        assert_(qc1.input_states[2] == "0")
        assert_(qc1.input_states[3] == "0")
        assert_(qc1.input_states[6] == "0")
        assert_(qc1.input_states[1] == "+")
        assert_(qc1.input_states[4] == "+")

        assert_(qc1.output_states[2] == None)        
        assert_(qc1.output_states[1] == "A")
        assert_(qc1.output_states[4] == "A")
        assert_(qc1.output_states[9] == "A")

        assert_(qc1.output_states[0] == "beta")