def compile_circuit(self, abstract_circuit: QCircuit, variables=None, *args, **kwargs) -> QCircuit: """ compile a circuit. Parameters ---------- abstract_circuit: QCircuit the circuit to compile. variables: (Default value = None): list of the variables whose gates, specifically, must compile. Used to prevent excess compilation in gates whose parameters are fixed. Default: compile every single gate. args kwargs Returns ------- QCircuit; a compiled circuit. """ n_qubits = abstract_circuit.n_qubits compiled = QCircuit(abstract_circuit.gates) if variables is None: # check & compile all gates gatelist = enumerate(abstract_circuit.gates) else: # check & compile only gates which depend on variables gatelist = [] for variable in variables: gatelist += abstract_circuit._parameter_map[variable] compiled_gates = [] for idx, gate in gatelist: cg = gate # print('into compile comes ', cg) controlled = gate.is_controlled() # order matters # first the real multi-target gates if controlled or self.trotterized: cg = compile_trotterized_gate(gate=cg) if controlled or self.gaussian: cg = compile_gaussian_gate(gate=cg) if controlled or self.exponential_pauli: cg = compile_exponential_pauli_gate(gate=cg) if self.swap: cg = compile_swap(gate=cg) # now every other multitarget gate which might be defined if self.multitarget: cg = compile_multitarget(gate=cg) if self.multicontrol: raise NotImplementedError( "Multicontrol compilation does not work yet") if self.hadamard_power: cg = compile_h_power(gate=cg) if self.phase_to_z: cg = compile_phase_to_z(gate=cg) if self.power: cg = compile_power_gate(gate=cg) if self.phase: cg = compile_phase(gate=cg) if controlled: if self.cc_max: cg = compile_to_cc(gate=cg) if self.controlled_exponential_pauli: cg = compile_exponential_pauli_gate(gate=cg) if self.hadamard_power: cg = compile_h_power(gate=cg) if self.controlled_power: cg = compile_power_gate(gate=cg) if self.controlled_phase: cg = compile_controlled_phase(gate=cg) if self.toffoli: cg = compile_toffoli(gate=cg) if self.phase: cg = compile_phase(gate=cg) if self.controlled_rotation: cg = compile_controlled_rotation(gate=cg) if self.cc_max: cg = compile_to_cc(gate=cg) compiled_gates.append((idx, cg)) if len(compiled_gates) == 0: return abstract_circuit else: pos, cgs = zip(*compiled_gates) compiled = abstract_circuit.replace_gates(positions=pos, circuits=cgs) return compiled
def compile_circuit(self, abstract_circuit: QCircuit, variables=None, *args, **kwargs) -> QCircuit: """ compile a circuit. Parameters ---------- abstract_circuit: QCircuit the circuit to compile. variables: (Default value = None): list of the variables whose gates, specifically, must compile. Used to prevent excess compilation in gates whose parameters are fixed. Default: compile every single gate. args kwargs Returns ------- QCircuit; a compiled circuit. """ n_qubits = abstract_circuit.n_qubits compiled = QCircuit(abstract_circuit.gates) if variables is None: # check & compile all gates gatelist = enumerate(abstract_circuit.gates) else: # check & compile only gates which depend on variables gatelist = [] for variable in variables: gatelist += abstract_circuit._parameter_map[variable] compiled_gates = [] for idx, gate in gatelist: cg = gate controlled = gate.is_controlled() if self.gradient_mode and (hasattr(cg, "eigenvalues_magnitude") or hasattr(cg, "shifted_gates")): compiled_gates.append((idx, QCircuit.wrap_gate(cg))) continue else: if hasattr(cg, "compile"): cg = QCircuit.wrap_gate(cg.compile()) for g in cg.gates: if g.is_controlled(): controlled = True # order matters # first the real multi-target gates if controlled or self.trotterized: cg = compile_trotterized_gate(gate=cg) if controlled or self.generalized_rotation: cg = compile_generalized_rotation_gate(gate=cg) if controlled or self.exponential_pauli: cg = compile_exponential_pauli_gate(gate=cg) if self.swap: cg = compile_swap(gate=cg) if self.phase_to_z: cg = compile_phase_to_z(gate=cg) if self.power: cg = compile_power_gate(gate=cg) if self.phase: cg = compile_phase(gate=cg) if self.ch_gate: cg = compile_ch(gate=cg) if self.y_gate: cg = compile_y(gate=cg) if self.ry_gate: cg = compile_ry(gate=cg, controlled_rotation=self.controlled_rotation) if controlled: if self.cc_max or self.multicontrol: cg = compile_to_single_control(gate=cg) if self.controlled_exponential_pauli: cg = compile_exponential_pauli_gate(gate=cg) if self.controlled_power: cg = compile_controlled_power(gate=cg) if self.controlled_phase: cg = compile_controlled_phase(gate=cg) if self.phase: cg = compile_phase(gate=cg) if self.toffoli: cg = compile_toffoli(gate=cg) if self.phase: cg = compile_phase(gate=cg) if self.controlled_rotation: cg = compile_controlled_rotation(gate=cg) compiled_gates.append((idx, cg)) if len(compiled_gates) == 0: return abstract_circuit else: pos, cgs = zip(*compiled_gates) compiled = abstract_circuit.replace_gates(positions=pos, circuits=cgs) return compiled