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)
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)