This isn't an issue with fondq, but I'm new to colabs, so I'm not sure how to suggest a fix to a colab. If there is a repo where I can submit a PR, then let me know.
In tutorial_01, "Introduction - Colab" from Cirq for NISQ near the end there is an exercise to create a Point Optimizer for CNOTs sandwiched with two H gates. The solution is only a redundant Hadamard optimizer. Perhaps the exercise changed after or vice versa. Anyhow, I wrote a HCXHOptimizer that you can throw in the Solution panel:
class HCXHOptimizer(cirq.PointOptimizer):
"""Replaces a CNOT sandwiched by H gates with a flipped CNOT."""
# The circuit to improve
# The index of the moment with the operation to focus on
# The operation to focus improvements upon
def optimization_at(self, circuit, index, op):
if isinstance(op, cirq.GateOperation) and (op.gate == cirq.H):
# Finds the index of the next moment that touches the given qubits.
next_op_index = circuit.next_moment_operating_on(op.qubits, index + 1)
qubit = op.qubits[0]
# If the next index exists
if next_op_index is not None:
# Get the operation at the existing index
next_op = circuit.operation_at(qubit, next_op_index)
if isinstance(next_op, cirq.GateOperation) and (next_op.gate == cirq.CNOT):
other_qubit = next_op.qubits[1]
cnot_index = next_op_index
cnot_op = next_op
next_op_index = circuit.next_moment_operating_on(op.qubits, next_op_index + 1)
next_op = circuit.operation_at(qubit, next_op_index)
if isinstance(next_op, cirq.GateOperation) and (next_op.gate == cirq.H):
other_op_index = circuit.prev_moment_operating_on(cnot_op.qubits, cnot_index)
other_op = circuit.operation_at(other_qubit, other_op_index)
if isinstance(other_op, cirq.GateOperation) and (other_op.gate == cirq.H):
other_op_index = circuit.next_moment_operating_on(cnot_op.qubits, cnot_index + 1)
other_op = circuit.operation_at(other_qubit, other_op_index)
if isinstance(other_op, cirq.GateOperation) and (other_op.gate == cirq.H):
new_op = cirq.CNOT(other_qubit, qubit)
# see https://cirq.readthedocs.io/en/stable/generated/cirq.PointOptimizationSummary.html?highlight=pointoptimizationsummary
return cirq.PointOptimizationSummary(
clear_span = next_op_index - index + 1, # Range of moments to affect.
clear_qubits = cnot_op.qubits, # The set of qubits that should be cleared with each affected moment
new_operations = [new_op] # The operations to replace
)
return None
# The optimizer
opt = HCXHOptimizer()
a = cirq.NamedQubit("a")
b = cirq.NamedQubit("b")
# Unoptimized circuit
circuit = cirq.Circuit(cirq.H(a), cirq.H(b), cirq.CNOT(a, b), cirq.H(a), cirq.H(b))
print('Before\n{}\n'. format(circuit))
# Optimized circuit
opt.optimize_circuit(circuit)
print('After HCX opt\n{}\n'.format(circuit))
# We can remove the empty moments
remempty = cirq.DropEmptyMoments()
remempty.optimize_circuit(circuit)
print('After Drop opt\n{}\n'.format(circuit))
This isn't an issue with fondq, but I'm new to colabs, so I'm not sure how to suggest a fix to a colab. If there is a repo where I can submit a PR, then let me know.
In tutorial_01, "Introduction - Colab" from Cirq for NISQ near the end there is an exercise to create a Point Optimizer for CNOTs sandwiched with two H gates. The solution is only a redundant Hadamard optimizer. Perhaps the exercise changed after or vice versa. Anyhow, I wrote a HCXHOptimizer that you can throw in the Solution panel: