Skip to content

"Simplify flipped CNOTs" exercise in intro colab has wrong solution #1

Description

@amirebrahimi

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))

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions