Beispiel #1
0
def move_pauli_strings_into_circuit(
        circuit_left: Union[circuits.Circuit, circuits.CircuitDag],
        circuit_right: circuits.Circuit) -> circuits.Circuit:
    if isinstance(circuit_left, circuits.CircuitDag):
        string_dag = circuits.CircuitDag(pauli_string_reorder_pred,
                                         circuit_left)
    else:
        string_dag = pauli_string_dag_from_circuit(
            cast(circuits.Circuit, circuit_left))
    output_ops = list(circuit_right.all_operations())

    rightmost_nodes = (set(string_dag.nodes()) -
                       set(before for before, _ in string_dag.edges()))

    while rightmost_nodes:
        # Sort the pauli string placements based on paulistring length and
        # furthest possible distance in circuit_right
        placements = _sorted_best_string_placements(rightmost_nodes,
                                                    output_ops)
        last_index = len(output_ops)

        # Pick the Pauli string that can be moved furthest through
        # the Clifford circuit
        for best_string_op, best_index, best_node in placements:

            assert best_index <= last_index, (
                "Unexpected insertion index order,"
                " {} >= {}, len: {}".format(best_index, last_index,
                                            len(output_ops)))

            last_index = best_index
            output_ops.insert(best_index, best_string_op)
            # Remove the best one from the dag and update rightmost_nodes
            rightmost_nodes.remove(best_node)
            rightmost_nodes.update(
                pred_node for pred_node in string_dag.predecessors(best_node)
                if len(string_dag.succ[pred_node]) <= 1)
            string_dag.remove_node(best_node)

    assert not string_dag.nodes(), 'There was a cycle in the CircuitDag'

    return circuits.Circuit(output_ops,
                            strategy=circuits.InsertStrategy.EARLIEST,
                            device=circuit_right.device)
Beispiel #2
0
def move_pauli_strings_into_circuit(
        circuit_left: Union[circuits.Circuit, circuits.CircuitDag],
        circuit_right: circuits.Circuit) -> circuits.Circuit:
    if isinstance(circuit_left, circuits.CircuitDag):
        string_dag = circuits.CircuitDag(pauli_string_reorder_pred,
                                         circuit_left)
    else:
        string_dag = pauli_string_dag_from_circuit(
            cast(circuits.Circuit, circuit_left))
    output_ops = list(circuit_right.all_operations())

    rightmost_nodes = (set(string_dag.nodes) -
                       set(before for before, _ in string_dag.edges))

    while rightmost_nodes:
        # Pick the Pauli string that can be moved furthest through the Clifford
        # circuit
        best_string_op, best_index, best_node = max(
            _possible_string_placements(rightmost_nodes, output_ops),
            key=lambda placement:
            (-len(placement[0].pauli_string), placement[1]))

        # Place the best one into the output circuit
        output_ops.insert(best_index, best_string_op)
        # Remove the best one from the dag and update rightmost_nodes
        rightmost_nodes.remove(best_node)
        rightmost_nodes.update(
            pred_node for pred_node in string_dag.predecessors(best_node)
            if len(string_dag.succ[pred_node]) <= 1)
        string_dag.remove_node(best_node)

    assert not string_dag.nodes, 'There was a cycle in the CircuitDag'

    return circuits.Circuit.from_ops(output_ops,
                                     strategy=circuits.InsertStrategy.EARLIEST,
                                     device=circuit_right.device)