def pswap(phi: float) -> MatrixGate: """Returns a Cirq MatrixGate for pyQuil's PSWAP gate. Args: phi: Gate parameter (in radians). Returns: A MatrixGate equivalent to a PSWAP gate of given angle. """ pswap_matrix = np.array([ [1, 0, 0, 0], [0, 0, np.exp(1j * phi), 0], [0, np.exp(1j * phi), 0, 0], [0, 0, 0, 1], ], dtype=complex) return MatrixGate(pswap_matrix)
def circuit_from_quil(quil: str) -> Circuit: """Convert a Quil program to a Cirq Circuit. Args: quil: The Quil program to convert. Returns: A Cirq Circuit generated from the Quil program. Raises: UnsupportedQuilInstruction: Cirq does not support the specified Quil instruction. UndefinedQuilGate: Cirq does not support the specified Quil gate. References: https://github.com/rigetti/pyquil """ circuit = Circuit() defined_gates = SUPPORTED_GATES.copy() instructions = parse(quil) for inst in instructions: # Add DEFGATE-defined gates to defgates dict using MatrixGate. if isinstance(inst, DefGate): if inst.parameters: raise UnsupportedQuilInstruction( "Parameterized DEFGATEs are currently unsupported.") defined_gates[inst.name] = MatrixGate(inst.matrix) # Pass when encountering a DECLARE. elif isinstance(inst, Declare): pass # Convert pyQuil gates to Cirq operations. elif isinstance(inst, PyQuilGate): quil_gate_name = inst.name quil_gate_params = inst.params line_qubits = list(LineQubit(q.index) for q in inst.qubits) if quil_gate_name not in defined_gates: raise UndefinedQuilGate( f"Quil gate {quil_gate_name} not supported in Cirq.") cirq_gate_fn = defined_gates[quil_gate_name] if quil_gate_params: circuit += cirq_gate_fn(*quil_gate_params)(*line_qubits) else: circuit += cirq_gate_fn(*line_qubits) # Convert pyQuil MEASURE operations to Cirq MeasurementGate objects. elif isinstance(inst, PyQuilMeasurement): line_qubit = LineQubit(inst.qubit.index) if inst.classical_reg is None: raise UnsupportedQuilInstruction( f"Quil measurement {inst} without classical register " f"not currently supported in Cirq.") quil_memory_reference = inst.classical_reg.out() circuit += MeasurementGate(1, key=quil_memory_reference)(line_qubit) # Raise a targeted error when encountering a PRAGMA. elif isinstance(inst, Pragma): raise UnsupportedQuilInstruction(PRAGMA_ERROR) # Raise a targeted error when encountering a RESET. elif isinstance(inst, (Reset, ResetQubit)): raise UnsupportedQuilInstruction(RESET_ERROR) # Raise a general error when encountering an unconsidered type. else: raise UnsupportedQuilInstruction( f"Quil instruction {inst} of type {type(inst)} not currently supported in Cirq." ) return circuit