Example #1
0
def test_define_qft():
    def qft3(q0, q1, q2):
        p = Program()
        p.inst(H(q2),
               CPHASE(pi / 2.0)(q1, q2), H(1),
               CPHASE(pi / 4.0)(q0, q2),
               CPHASE(pi / 2.0)(q0, q1), H(q0), SWAP(q0, q2))
        return p

    # I(2) is to force 3 qubits in state prep program.
    state_prep = Program().inst(X(0))

    prog = state_prep + qft3(0, 1, 2)
    output = prog.out()
    assert output == 'X 0\nH 2\nCPHASE(1.5707963267948966) 1 2\nH 1\nCPHASE(0.7853981633974483) 0 ' \
                     '2\nCPHASE(1.5707963267948966) 0 1\nH 0\nSWAP 0 2\n'
Example #2
0
def test_reset():
    p = Program()
    p.reset(0)
    p.reset()
    assert p.out() == "RESET 0\nRESET\n"

    program = Program()
    qubit = QubitPlaceholder()
    # address_qubits() won't work unless there's a gate besides
    # RESET on a QubitPlaceholder, this is just here to make
    # addressing work
    program += X(qubit)

    program += RESET(qubit)
    program = address_qubits(program)
    assert program.out() == "X 0\nRESET 0\n"
Example #3
0
def test_control_flows_2():
    # create a program that branches based on the value of a classical register
    x_prog = Program(X(0))
    z_prog = Program()
    branch = Program(H(1)).measure(1, MemoryReference("ro", 1)) \
        .if_then(MemoryReference("ro", 1), x_prog, z_prog) \
        .measure(0, MemoryReference("ro", 0))
    assert branch.out() == ('DECLARE ro BIT[2]\n'
                            'H 1\n'
                            'MEASURE 1 ro[1]\n'
                            'JUMP-WHEN @THEN1 ro[1]\n'
                            'JUMP @END2\n'
                            'LABEL @THEN1\n'
                            'X 0\n'
                            'LABEL @END2\n'
                            'MEASURE 0 ro[0]\n')
Example #4
0
def test_tomo_experiment():
    expts = [
        ExperimentSetting(TensorProductState(),
                          sX(0) * sY(1)),
        ExperimentSetting(plusZ(0), sZ(0)),
    ]

    suite = TomographyExperiment(settings=expts, program=Program(X(0), Y(1)))
    assert len(suite) == 2
    for e1, e2 in zip(expts, suite):
        # experiment suite puts in groups of length 1
        assert len(e2) == 1
        e2 = e2[0]
        assert e1 == e2
    prog_str = str(suite).splitlines()[3:5]
    assert prog_str == EXPERIMENT_REPR.splitlines()[4:6]
Example #5
0
def test_all_instructions():
    pq = Program(H(0), X(1), RX(1.2, 2), CNOT(0, 1), CCNOT(0, 1, 2))
    ro = pq.declare("ro")
    pq.measure(0, ro)
    pq.defgate("mygate", [[1, 0], [0, 1]])
    pq.inst(("mygate", 0))
    pq.reset(0)
    pq += Program(NEG(ro), AND(ro, ro), ADD(ro, 1), EQ(ro, ro, ro))
    pq += Program(EXCHANGE(ro, ro), CONVERT(ro, ro))
    pq += Program(LOAD(ro, ro, ro), STORE(ro, ro, ro))

    G = QuilControlFlowGraph(pq)

    assert len(G.blocks) == 1
    assert set(G.nodes) == set([0])
    assert set(G.edges) == set()
    assert G.is_dag()
Example #6
0
def test_merge_with_pauli_noise():
    p = Program(X(0)).inst(Z(0))
    probs = [0.0, 1.0, 0.0, 0.0]
    merged = merge_with_pauli_noise(p, probs, [0])
    assert (merged.out() == """DEFGATE pauli_noise:
    1.0, 0
    0, 1.0

PRAGMA ADD-KRAUS pauli_noise 0 "(0.0 0.0 0.0 0.0)"
PRAGMA ADD-KRAUS pauli_noise 0 "(0.0 1.0 1.0 0.0)"
PRAGMA ADD-KRAUS pauli_noise 0 "(0.0 0.0 0.0 0.0)"
PRAGMA ADD-KRAUS pauli_noise 0 "(0.0 0.0 0.0 -0.0)"
X 0
pauli_noise 0
Z 0
pauli_noise 0
""")
Example #7
0
    def test_run_circuitset_and_measure(self, backend):
        # Given
        num_circuits = 10
        circuit = Circuit(Program(X(0), CNOT(1, 2)))
        n_samples = 100
        # When
        backend.n_samples = n_samples
        measurements_set = backend.run_circuitset_and_measure([circuit] * num_circuits)
        # Then
        assert len(measurements_set) == num_circuits
        for measurements in measurements_set:
            assert len(measurements.bitstrings) == n_samples

            # Then (since SPAM error could result in unexpected bitstrings, we make sure the most common bitstring is
            #   the one we expect)
            counts = measurements.get_counts()
            assert max(counts, key=counts.get) == "100"
Example #8
0
def test_to_latex():
    """A test to give full coverage of latex_generation and latex_config."""
    qubits = range(3)
    p = Program()
    p.inst(X(qubits[0]), Y(qubits[0]), CZ(qubits[0], qubits[2]),
           SWAP(qubits[0], qubits[1]), MEASURE(qubits[0], None),
           CNOT(qubits[2], qubits[0]))
    _ = to_latex(p)

    # Modify settings to access non-standard control paths.
    settings = get_default_settings()
    settings['gates']['AllocateQubitGate']['draw_id'] = True
    settings['gate_shadow'] = None
    _ = to_latex(p, settings)

    settings['control']['shadow'] = True
    _ = to_latex(p, settings)
Example #9
0
def test_control_flows_2():
    # create a program that branches based on the value of a classical register
    x_prog = Program(X(0))
    z_prog = Program()
    branch = (Program(Declare("ro", "BIT", 2),
                      H(1)).measure(1, MemoryReference("ro", 1)).if_then(
                          MemoryReference("ro", 1), x_prog,
                          z_prog).measure(0, MemoryReference("ro", 0)))
    assert branch.out() == ("DECLARE ro BIT[2]\n"
                            "H 1\n"
                            "MEASURE 1 ro[1]\n"
                            "JUMP-WHEN @THEN1 ro[1]\n"
                            "JUMP @END2\n"
                            "LABEL @THEN1\n"
                            "X 0\n"
                            "LABEL @END2\n"
                            "MEASURE 0 ro[0]\n")
def simulate_error(primal: nx.Graph, dual: nx.Graph, p=None, phase_flips=None,
                   bit_flips=None):
    '''Given a code defined by a primal and dual graph, applies noise under the
    independent noise model.

    :param primal: Primal graph of the code
    :param dual: Dual graph of the code
    :param p: Probability with which to apply bit and phase flips
    :param phase_flips, bit_flips: Lists of edges to apply bit/phase flips to,
        if working in a deterministic setting (in this case, set p=None)
    :returns: Program for primal and dual graphs representing the applied
        errors, and lists of edges for each graph where phase and bit flips
        were applied for debugging
    '''
    if p is None:
        assert phase_flips is not None
        assert bit_flips is not None
    else:
        # Randomly choose which qubits will have bit/phase flip errors
        # Working under the independent noise model; since the toric code is a
        # CSS code, we can analyze bit and phase flip errors seperately

        assert phase_flips is None
        assert bit_flips is None

        phase_flips = set()
        for edge in primal.edges:
            if weighted_flip(p):
                phase_flips.add(edge)
        bit_flips = set()
        for edge in dual.edges:
            if weighted_flip(p):
                bit_flips.add(edge)

    primal_pq = Program()
    dual_pq = Program()

    # Apply the errors we selected above to the necessary qubits
    for p_edge in primal.edges:
        if p_edge in phase_flips:
            primal_pq += Z(primal.edges[p_edge]['data_qubit'])
    for d_edge in dual.edges:
        if d_edge in bit_flips:
            dual_pq += X(dual.edges[d_edge]['data_qubit'])

    return primal_pq, phase_flips, dual_pq, bit_flips
Example #11
0
def _ops_bool_to_prog(ops_bool: Tuple[bool], qubits: List[int]) -> Program:
    """
    :param ops_bool: tuple of booleans specifying the operation to be carried out on `qubits`
    :param qubits: list specifying the qubits to be carried operations on
    :return: Program with the operations specified in `ops_bool` on the qubits specified in
        `qubits`
    """
    assert len(ops_bool) == len(qubits), "Mismatch of qubits and operations"
    prog = Program()
    for i, op_bool in enumerate(ops_bool):
        if op_bool == 0:
            continue
        elif op_bool == 1:
            prog += Program(X(qubits[i]))
        else:
            raise ValueError("ops_bool should only consist of 0s and/or 1s")
    return prog
Example #12
0
    def test_readout_correction_works_run_circuitset_and_measure(self):
        # Given
        ibmq_api_token = os.getenv("ZAPATA_IBMQ_API_TOKEN")
        backend = QiskitBackend(
            device_name="ibmq_qasm_simulator",
            n_samples=1000,
            api_token=ibmq_api_token,
            readout_correction=True,
        )
        circuit = Circuit(Program(X(0), CNOT(1, 2)))

        # When
        backend.run_circuitset_and_measure([circuit] * 10)

        # Then
        assert backend.readout_correction
        assert backend.readout_correction_filter is not None
Example #13
0
def generate_2q_single_depth_experiment(rotation: Program,
                                        depth: int,
                                        exp_type: str,
                                        measurement_qubit: int,
                                        init_one: bool = False,
                                        axis: Tuple = None) -> Program:
    """
    A special variant of the 1q method that is specifically designed to calibrate a CPHASE gate. The
    ideal CPHASE is of the following form
        CPHASE(\phi) = diag(1,1,1,Exp[-i \phi]
    The imperfect CPHASE has two local Z rotations and a possible over (or under) rotation on the
    phase phi. Thus we have
        CPHASE(\Phi, \Theta_1, \Theta_2) = diag( exp(-a -b), exp(-a + b), exp(a-b), exp(a+b+c) )
        a = i \Theta_1 / 2,     b = i \Theta_2 / 2,     c = i \Phi

    The following experiments isolate the three angles using the state preparations |0>|+>, |+>|0>,
    |1>|+>, |+>|1> where the incurred phase is measured on the qubit initialized to the plus state.
    The four measurements are specified by setting the measurement qubit to either q1 or q2, and
    setting init_one to True indicating that the non-measurement qubit be prepared in the one state
    |1>.

    :param rotation: the program specifying the gate whose angle of rotation we wish to estimate.
    :param depth: the number of times we apply the rotation in the experiment
    :param exp_type: X or Y, specifying which operator to measure at the end of the experiment
    :param measurement_qubit: the qubit to be measured in this variant of the experiment
    :param axis: the axis of rotation. If none is specified, axis is assumed to be the Z axis. (rotation should be RZ)
    :param init_one: True iff the non-measurement qubit should be prepared in the 1 state.
    :param axis: the axis of rotation. If none is specified, axis is assumed to be the Z axis. (rotation should be RZ)
    :return: An estimate of some aspect of the CPHASE gate which depends on the measurement variant.
    """
    prog = Program()
    ro_bit = prog.declare("ro", "BIT", 1)
    qubits = rotation.get_qubits()
    non_measurement_qubit = list(qubits - {measurement_qubit})[0]
    prepare_state(prog, measurement_qubit)
    if init_one:
        prog.inst(X(non_measurement_qubit))
    for _ in range(depth):
        prog.inst(rotation)
    if axis:
        prog.inst(RZ(-axis[1], measurement_qubit))
        prog.inst(RY(-axis[0], measurement_qubit))
    local_pauli_eig_meas(prog, exp_type, measurement_qubit)
    prog.measure(measurement_qubit, ro_bit)
    return prog
Example #14
0
def test_is_protoquil():
    prog = Program(Declare('ro', 'BIT'), MEASURE(1, MemoryReference("ro", 0)),
                   H(1), RESET())
    validate_protoquil(prog)
    assert prog.is_protoquil()

    prog = Program(Declare('ro', 'BIT'), H(0), Y(1), CNOT(0, 1)) \
        .measure(0, MemoryReference("ro", 0)) \
        .if_then(MemoryReference("ro", 0), Program(X(0)), Program())
    with pytest.raises(ValueError):
        validate_protoquil(prog)
    assert not prog.is_protoquil()

    prog = Program(Declare('ro', 'BIT'), ClassicalNot(MemoryReference("ro",
                                                                      0)))
    with pytest.raises(ValueError):
        validate_protoquil(prog)
    assert not prog.is_protoquil()
Example #15
0
def test_control_flows():
    outer_loop = Program()
    classical_flag_register = outer_loop.declare('classical_flag_register',
                                                 'BIT')
    outer_loop += MOVE(classical_flag_register, 1)  # initialize

    inner_loop = Program()
    inner_loop += Program(X(0), H(0))
    inner_loop += MEASURE(0, classical_flag_register)

    # run inner_loop in a loop until classical_flag_register is 0
    outer_loop.while_do(classical_flag_register, inner_loop)
    assert outer_loop.out() == '\n'.join([
        "DECLARE classical_flag_register BIT[1]",
        "MOVE classical_flag_register 1", "LABEL @START1",
        "JUMP-UNLESS @END2 classical_flag_register", "X 0", "H 0",
        "MEASURE 0 classical_flag_register", "JUMP @START1", "LABEL @END2", ""
    ])
Example #16
0
def test_qpu_run(forest: ForestConnection):
    devices = get_devices(async_endpoint=forest.async_endpoint, api_key=forest.api_key,
                          user_id=forest.user_id, as_dict=True)

    for name, dev in devices.items():
        if not dev.is_online:
            continue

        # TODO: gh-372. No way to query whether a device is available for running
        pytest.xfail("Please fix after gh-372")
        qpu = QPU(connection=forest, device_name=name)
        bitstrings = qpu.run(
            quil_program=Program(X(0), MEASURE(0, 0)),
            classical_addresses=[0],
            trials=1000,
        )
        assert bitstrings.shape == (1000, 1)
        assert np.mean(bitstrings) > 0.8
Example #17
0
def test_qvm_run_only_pqer(forest: ForestConnection):
    qvm = QVM(connection=forest, gate_noise=[0.01] * 3, requires_executable=True)
    p = Program(Declare("ro", "BIT"), X(0), MEASURE(0, MemoryReference("ro")))
    p.wrap_in_numshots_loop(1000)

    with pytest.raises(TypeError) as e:
        qvm.load(p)
        qvm.run()
        qvm.wait()
    assert e.match(r".*Make sure you have explicitly compiled your program.*")

    nq = PyQuilExecutableResponse(program=p.out(), attributes={"num_shots": 1000})
    qvm.load(nq)
    qvm.run()
    qvm.wait()
    bitstrings = qvm.read_memory(region_name="ro")
    assert bitstrings.shape == (1000, 1)
    assert np.mean(bitstrings) > 0.8
Example #18
0
def test_out_vs_str():
    qs = QubitPlaceholder.register(6)
    pq = Program(
        Declare("ro", "BIT", 6),
        X(qs[0]),
        CNOT(qs[0], qs[4]),
        MEASURE(qs[5], MemoryReference("ro", 5)),
    )

    with pytest.raises(RuntimeError) as e:
        pq.out()
    assert e.match(r"Qubit q\d+ has not been assigned an index")

    string_version = str(pq)
    should_be_re = (
        r"DECLARE ro BIT\[6\]\nX \{q\d+\}\nCNOT \{q\d+\} \{q\d+\}\nMEASURE \{q\d+\} ro\[5\]\n"
    )
    assert re.fullmatch(should_be_re, string_version, flags=re.MULTILINE)
Example #19
0
    def build(self, a):
        pq = Program()

        code, x_qubits = to_qubits(1, self.n)
        pq += code
        code, b_qubits = to_qubits(0, self.n + 1)
        pq += code

        total_iters = 2 * (self.n)
        ro = pq.declare('ro', 'BIT', total_iters + len(x_qubits))

        c = QubitPlaceholder()
        curr_a = a
        '''
        code, ctrl_qubits = to_qubits(0, total_iters)
        pq += code
        for i in range(total_iters):
            ind = total_iters - 1 - i
            c = ctrl_qubits[ind]
            pq += H(c)
            pq += self.u_a(b_qubits, curr_a, c, x_qubits)
            curr_a = curr_a ** 2 % self.N
        for i in range(len(x_qubits)):
            pq += MEASURE(x_qubits[i], ro[total_iters + i])
        ctrl_qubits = ctrl_qubits[::-1]
        pq += self.inv_qft(ctrl_qubits)
        #print(wave.wavefunction(address_qubits(pq)))
        for i in range(total_iters):
            pq += MEASURE(ctrl_qubits[i], ro[i])
        '''
        a_vals = []
        for i in range(total_iters):
            a_vals.append(curr_a)
            curr_a = pow(curr_a, 2, self.N)
        for ind in range(total_iters - 1, -1, -1):
            pq += H(c)
            pq += self.u_a(b_qubits, a_vals[ind], c, x_qubits)
            pq += self.partial_inv_qft(c, ind, ro, total_iters)
            pq += MEASURE(c, ro[ind])

            then_prog = Program(X(c))
            pq.if_then(ro[ind], then_prog)

        return address_qubits(pq)
Example #20
0
def test_multi_qubit_qft():
    trial_prog = Program()
    trial_prog.inst(X(0), X(1), X(2))
    trial_prog = trial_prog + inverse_qft([0, 1, 2])
    
    result_prog = Program().inst([X(0), X(1), X(2),
                                     SWAP(0, 2), H(0),
                                     CPHASE(-1.5707963267948966, 0, 1),
                                     CPHASE(-0.7853981633974483, 0, 2),
                                     H(1), CPHASE(-1.5707963267948966, 1, 2),
                                     H(2)])
    
    assert trial_prog == result_prog
Example #21
0
def test_qvm_compile_pickiness(forest):
    p = Program(Declare("ro", "BIT"), X(0), MEASURE(0, MemoryReference("ro")))
    p.wrap_in_numshots_loop(1000)
    nq = PyQuilExecutableResponse(program=p.out(), attributes={"num_shots": 1000})

    # Ok, non-realistic
    qc = get_qc("9q-qvm")
    qc.run(p)

    # Also ok
    qc.run(nq)

    # Not ok
    qc = get_qc("9q-square-qvm")
    with pytest.raises(TypeError):
        qc.run(p)

    # Yot ok
    qc.run(nq)
Example #22
0
def test_qubit_placeholder():
    p = Program()

    p.inst(H(0))  # H 0

    q1 = QubitPlaceholder()  # q1 = 1
    q2 = QubitPlaceholder()  # q2 = 3

    p.inst(CNOT(q1, q2))  # CNOT 1 3

    p.inst(H(2))

    q3 = QubitPlaceholder()  # q3 = 4

    p.inst(X(q3))  # X 4

    with pytest.raises(RuntimeError) as e:
        _ = p.out()
    assert e.match(r"Qubit q\d+ has not been assigned an index")
Example #23
0
def test_qubit_placeholder_2():
    p = Program()

    p.inst(H(0))  # H 0

    q1 = QubitPlaceholder()  # q1 = 1
    q2 = QubitPlaceholder()  # q2 = 3

    p.inst(CNOT(q1, q2))  # CNOT 1 3

    p.inst(H(2))

    q3 = QubitPlaceholder()  # q3 = 4

    p.inst(X(q3))  # X 4
    with pytest.raises(ValueError) as e:
        _ = address_qubits(p, {q1: 1, q2: 3, q3: 4})

    assert e.match("Your program mixes instantiated qubits with placeholders")
Example #24
0
def test_x_oracle_one_grover(x_oracle):
    """Testing that Grover's algorithm with an oracle that applies an X gate to the query bit works,
     with one iteration."""
    x_oracle_grover = Program()
    qubit0 = x_oracle_grover.alloc()
    qubits = [qubit0]
    oracle, query_qubit = x_oracle
    with patch("pyquil.quil.Program.alloc") as mock_alloc:
        mock_alloc.return_value = qubit0
    generated_x_oracle_grover = Grover().oracle_grover(oracle, qubits, 1)
    # First we put the input into uniform superposition.
    x_oracle_grover.inst(H(qubit0))
    # Now an oracle is applied.
    x_oracle_grover.inst(X(query_qubit))
    # We now apply the diffusion operator.
    x_oracle_grover.inst(H(qubit0))
    x_oracle_grover.inst(Z(qubit0))
    x_oracle_grover.inst(H(qubit0))
    assert generated_x_oracle_grover == x_oracle_grover
Example #25
0
def prep_qubits(qubits: list, n: int):
    """
    Generate a quil program which prepares given qubits in a state representing number n.

    :param n: the number to write
    :param qubits: qubit indexes to write the number n

    :return: circuit to write number n on given qubits.
    """
    p = Program()

    for qubit in qubits:
        if n % 2 == 1:
            p.inst(X(qubit))
        else:
            p.inst(I(qubit))
        n = int(n/2)
    
    return p
Example #26
0
def teleport(start_index, end_index, ancilla_index):
    """Teleport a qubit from start to end using an ancilla qubit
    """
    p = make_bell_pair(end_index, ancilla_index)

    # do the teleportation
    p.inst(CNOT(start_index, ancilla_index))
    p.inst(H(start_index))

    # measure the results and store them in classical registers [0] and [1]
    p.measure(start_index, 0)
    p.measure(ancilla_index, 1)

    p.if_then(1, X(2))
    p.if_then(0, Z(2))

    p.measure(end_index, 2)

    return p
Example #27
0
def test_alloc():
    p = Program()

    p.inst(H(0))  # H 0

    q1 = p.alloc()  # q1 = 1
    q2 = p.alloc()  # q2 = 3

    p.inst(CNOT(q1, q2))  # CNOT 1 3

    p.inst(H(2))

    q3 = p.alloc()  # q3 = 4

    p.inst(X(q3))  # X 4

    with pytest.raises(RuntimeError) as e:
        _ = p.out()
    assert e.match(r'Qubit q\d+ has not been assigned an index')
Example #28
0
def test_tomo_experiment_pre_grouped():
    expts = [
        [
            ExperimentSetting(TensorProductState(), sX(0) * sI(1)),
            ExperimentSetting(TensorProductState(), sI(0) * sX(1)),
        ],
        [
            ExperimentSetting(TensorProductState(), sZ(0) * sI(1)),
            ExperimentSetting(TensorProductState(), sI(0) * sZ(1)),
        ],
    ]

    suite = Experiment(settings=expts, program=Program(X(0), Y(1)))
    assert len(suite) == 2  # number of groups
    for es1, es2 in zip(expts, suite):
        for e1, e2 in zip(es1, es2):
            assert e1 == e2
    prog_str = str(suite).splitlines()[3:5]
    assert prog_str == EXPERIMENT_REPR.splitlines()[4:6]
    def run_bv(self, bit):
        # initialize all attributes
        self._run_init(bit)
        qvm = get_qc('9q-square-qvm')

        # To get a
        oracle = self._create_oracle(bit)
        a_circuit = Program()
        a_ro = a_circuit.declare('ro', 'BIT', len(self.qubits) + 1)

        bv_circuit = Program()
        bv_circuit.defgate("oracle", oracle)
        bv_circuit.inst(X(self.helper), H(self.helper))
        bv_circuit.inst([H(i) for i in self.qubits])
        bv_circuit.inst(
            tuple(["oracle"] +
                  sorted(self.qubits + [self.helper], reverse=True)))
        bv_circuit.inst([H(i) for i in self.qubits])

        a_circuit += bv_circuit
        a_circuit += [
            MEASURE(qubit, ro) for qubit, ro in zip(self.qubits, a_ro)
        ]

        a_executable = qvm.compile(a_circuit)

        for i in range(self.n_trials):
            a_results = qvm.run(a_executable)
            print("trial {} a:".format(i))
            pprint.pprint(a_results[0][::-1])

        # To get b use all 0s
        b_circuit = Program()
        b_ro = b_circuit.declare('ro', 'BIT', len(self.qubits) + 1)
        b_circuit += bv_circuit
        b_circuit += [MEASURE(self.helper, b_ro[self.helper])]
        b_executable = qvm.compile(b_circuit)

        for i in range(self.n_trials):
            b_results = qvm.run(b_executable)
            print("trial {} b:".format(i))
            pprint.pprint(b_results)
Example #30
0
def test_dagger():
    # these gates are their own inverses
    p = Program().inst(I(0), X(0), Y(0), Z(0),
                       H(0), CNOT(0,1), CCNOT(0,1,2),
                       SWAP(0,1), CSWAP(0,1,2))
    assert p.dagger().out() == 'CSWAP 0 1 2\nSWAP 0 1\n' \
                      'CCNOT 0 1 2\nCNOT 0 1\nH 0\n' \
                      'Z 0\nY 0\nX 0\nI 0\n'

    # these gates require negating a parameter
    p = Program().inst(PHASE(pi, 0), RX(pi, 0), RY(pi, 0),
                       RZ(pi, 0), CPHASE(pi, 0, 1),
                       CPHASE00(pi, 0, 1), CPHASE01(pi, 0, 1),
                       CPHASE10(pi, 0, 1), PSWAP(pi, 0, 1))
    assert p.dagger().out() == 'PSWAP(-3.141592653589793) 0 1\n' \
                               'CPHASE10(-3.141592653589793) 0 1\n' \
                               'CPHASE01(-3.141592653589793) 0 1\n' \
                               'CPHASE00(-3.141592653589793) 0 1\n' \
                               'CPHASE(-3.141592653589793) 0 1\n' \
                               'RZ(-3.141592653589793) 0\n' \
                               'RY(-3.141592653589793) 0\n' \
                               'RX(-3.141592653589793) 0\n' \
                               'PHASE(-3.141592653589793) 0\n'

    # these gates are special cases
    p = Program().inst(S(0), T(0), ISWAP(0, 1))
    assert p.dagger().out() == 'PSWAP(1.5707963267948966) 0 1\n' \
                               'RZ(0.7853981633974483) 0\n' \
                               'PHASE(-1.5707963267948966) 0\n'

    # must invert defined gates
    G = np.array([[0, 1], [0+1j, 0]])
    p = Program().defgate("G", G).inst(("G", 0))
    assert p.dagger().out() == 'DEFGATE G-INV:\n' \
                               '    0.0+-0.0i, 0.0-1.0i\n' \
                               '    1.0+-0.0i, 0.0+-0.0i\n\n' \
                               'G-INV 0\n'

    # can also pass in a list of inverses
    inv_dict = {"G":"J"}
    p = Program().defgate("G", G).inst(("G", 0))
    assert p.dagger(inv_dict=inv_dict).out() == 'J 0\n'