ReVa_AI_Vaccine_Design / qiskit /converters /circuit_to_instruction.py
herutriana44's picture
First Commit
b7d9967 verified
# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2019.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""Helper function for converting a circuit to an instruction."""
from qiskit.exceptions import QiskitError
from qiskit.circuit.instruction import Instruction
from qiskit.circuit.quantumregister import QuantumRegister
from qiskit.circuit.classicalregister import ClassicalRegister, Clbit
def circuit_to_instruction(circuit, parameter_map=None, equivalence_library=None, label=None):
"""Build an :class:`~.circuit.Instruction` object from a :class:`.QuantumCircuit`.
The instruction is anonymous (not tied to a named quantum register),
and so can be inserted into another circuit. The instruction will
have the same string name as the circuit.
Args:
circuit (QuantumCircuit): the input circuit.
parameter_map (dict): For parameterized circuits, a mapping from
parameters in the circuit to parameters to be used in the instruction.
If None, existing circuit parameters will also parameterize the
instruction.
equivalence_library (EquivalenceLibrary): Optional equivalence library
where the converted instruction will be registered.
label (str): Optional instruction label.
Raises:
QiskitError: if parameter_map is not compatible with circuit
Return:
qiskit.circuit.Instruction: an instruction equivalent to the action of the
input circuit. Upon decomposition, this instruction will
yield the components comprising the original circuit.
Example:
.. code-block::
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
from qiskit.converters import circuit_to_instruction
q = QuantumRegister(3, 'q')
c = ClassicalRegister(3, 'c')
circ = QuantumCircuit(q, c)
circ.h(q[0])
circ.cx(q[0], q[1])
circ.measure(q[0], c[0])
circ.rz(0.5, q[1]).c_if(c, 2)
circuit_to_instruction(circ)
"""
# pylint: disable=cyclic-import
from qiskit.circuit.quantumcircuit import QuantumCircuit
if parameter_map is None:
parameter_dict = {p: p for p in circuit.parameters}
else:
parameter_dict = circuit._unroll_param_dict(parameter_map)
if parameter_dict.keys() != circuit.parameters:
raise QiskitError(
(
"parameter_map should map all circuit parameters. "
"Circuit parameters: {}, parameter_map: {}"
).format(circuit.parameters, parameter_dict)
)
out_instruction = Instruction(
name=circuit.name,
num_qubits=circuit.num_qubits,
num_clbits=circuit.num_clbits,
params=[*parameter_dict.values()],
label=label,
)
out_instruction.condition = None
target = circuit.assign_parameters(parameter_dict, inplace=False)
if equivalence_library is not None:
equivalence_library.add_equivalence(out_instruction, target)
regs = []
if out_instruction.num_qubits > 0:
q = QuantumRegister(out_instruction.num_qubits, "q")
regs.append(q)
if out_instruction.num_clbits > 0:
c = ClassicalRegister(out_instruction.num_clbits, "c")
regs.append(c)
qubit_map = {bit: q[idx] for idx, bit in enumerate(circuit.qubits)}
clbit_map = {bit: c[idx] for idx, bit in enumerate(circuit.clbits)}
definition = [
instruction.replace(
qubits=[qubit_map[y] for y in instruction.qubits],
clbits=[clbit_map[y] for y in instruction.clbits],
)
for instruction in target.data
]
# fix condition
for rule in definition:
condition = getattr(rule.operation, "condition", None)
if condition:
reg, val = condition
if isinstance(reg, Clbit):
rule.operation.condition = (clbit_map[reg], val)
elif reg.size == c.size:
rule.operation.condition = (c, val)
else:
raise QiskitError(
"Cannot convert condition in circuit with "
"multiple classical registers to instruction"
)
qc = QuantumCircuit(*regs, name=out_instruction.name)
for instruction in definition:
qc._append(instruction)
if circuit.global_phase:
qc.global_phase = circuit.global_phase
out_instruction.definition = qc
return out_instruction