def compose_back(self, input_circuit, wire_map={}):
"""Apply the input circuit to the output of this circuit.
The two bases must be "compatible" or an exception occurs.
A subset of input qubits of the input circuit are mapped
to a subset of output qubits of this circuit.
wire_map[input_qubit_to_input_circuit] = output_qubit_of_self
"""
union_basis = self._make_union_basis(input_circuit)
union_gates = self._make_union_gates(input_circuit)
# Check the wire map for duplicate values
if len(set(wire_map.values())) != len(wire_map):
raise DAGCircuitError("duplicates in wire_map")
add_qregs = self._check_wiremap_registers(wire_map,
input_circuit.qregs,
self.qregs)
for register in add_qregs:
self.add_qreg(register[0], register[1])
add_cregs = self._check_wiremap_registers(wire_map,
input_circuit.cregs,
self.cregs)
for register in add_cregs:
self.add_creg(register[0], register[1])
self._check_wiremap_validity(wire_map, input_circuit.input_map,
self.output_map, input_circuit)
# Compose
self.basis = union_basis
self.gates = union_gates
topological_sort = nx.topological_sort(input_circuit.multi_graph)
for node in topological_sort:
nd = input_circuit.multi_graph.node[node]
if nd["type"] == "in":
# if in wire_map, get new name, else use existing name
m_name = wire_map.get(nd["name"], nd["name"])
# the mapped wire should already exist
assert m_name in self.output_map, \
"wire (%s,%d) not in self" % (m_name[0], m_name[1])
assert nd["name"] in input_circuit.wire_type, \
"inconsistent wire_type for (%s,%d) in input_circuit" \
% (nd["name"][0], nd["name"][1])
elif nd["type"] == "out":
# ignore output nodes
pass
elif nd["type"] == "op":
condition = self._map_condition(wire_map, nd["condition"])
self._check_condition(nd["name"], condition)
m_qargs = list(map(lambda x: wire_map.get(x, x), nd["qargs"]))
m_cargs = list(map(lambda x: wire_map.get(x, x), nd["cargs"]))
self.apply_operation_back(nd["name"], m_qargs, m_cargs,
nd["params"], condition)
else:
assert False, "bad node type %s" % nd["type"]
评论列表
文章目录