def run(self, dag): """Run the Optimize1qGatesDecomposition pass on `dag`. Args: dag (DAGCircuit): the DAG to be optimized. Returns: DAGCircuit: the optimized DAG. """ if not self.basis: logger.info("Skipping pass because no basis is set") return dag runs = dag.collect_1q_runs() identity_matrix = np.eye(2) for run in runs: single_u3 = False # Don't try to optimize a single 1q gate, except for U3 if len(run) <= 1: params = run[0].op.params # Remove single identity gates if len(params) > 0 and np.array_equal(run[0].op.to_matrix(), identity_matrix): dag.remove_op_node(run[0]) continue if (isinstance(run[0].op, U3Gate) and np.isclose(float(params[0]), [0, np.pi / 2], atol=1e-12, rtol=0).any()): single_u3 = True else: continue new_circs = [] operator = Operator(run[0].op) for gate in run[1:]: operator = operator.compose(gate.op) for decomposer in self.basis: new_circs.append(decomposer(operator)) if new_circs: new_circ = min(new_circs, key=len) if (len(run) > len(new_circ) or (single_u3 and new_circ.data[0][0].name != 'u3')): new_dag = circuit_to_dag(new_circ) dag.substitute_node_with_dag(run[0], new_dag) # Delete the other nodes in the run for current_node in run[1:]: dag.remove_op_node(current_node) return dag
def run(self, dag): """Run the Optimize1qGatesDecomposition pass on `dag`. Args: dag (DAGCircuit): the DAG to be optimized. Returns: DAGCircuit: the optimized DAG. """ if not self.basis: logger.info("Skipping pass because no basis is set") return dag runs = dag.collect_1q_runs() identity_matrix = np.eye(2) for run in runs: # Don't try to optimize a single 1q gate if len(run) <= 1: params = run[0].op.params # Remove single identity gates if len(params) > 0 and np.array_equal(run[0].op.to_matrix(), identity_matrix): dag.remove_op_node(run[0]) continue new_circs = [] operator = Operator(run[0].op) for gate in run[1:]: operator = operator.compose(gate.op) for decomposer in self.basis: new_circs.append(decomposer(operator)) if new_circs: new_circ = min(new_circs, key=len) if len(run) > len(new_circ): new_dag = circuit_to_dag(new_circ) dag.substitute_node_with_dag(run[0], new_dag) # Delete the other nodes in the run for current_node in run[1:]: dag.remove_op_node(current_node) return dag