Пример #1
0
    def solve(self, output_mode=None, output_file_name=None):
        result_depth, list_scheduled_gate_name, list_scheduled_gate_qubits, final_mapping = super(
        ).solve("IR")
        circuit = Circuit()
        for t in range(result_depth):
            moment = Moment()
            for i, qubits in enumerate(list_scheduled_gate_qubits[t]):
                if isinstance(qubits, int):
                    moment = moment.with_operation(
                        GateOperation(list_scheduled_gate_name[t][i],
                                      (self.map_to_cirq_qubit[qubits], )))
                else:
                    if list_scheduled_gate_name[t][i] == "SWAP":
                        moment = moment.with_operation(
                            GateOperation(SWAP,
                                          (self.map_to_cirq_qubit[qubits[0]],
                                           self.map_to_cirq_qubit[qubits[1]])))
                    else:
                        moment = moment.with_operation(
                            GateOperation(list_scheduled_gate_name[t][i],
                                          (self.map_to_cirq_qubit[qubits[0]],
                                           self.map_to_cirq_qubit[qubits[1]])))
            circuit += moment

        final_cirq_mapping = dict()
        for i in range(self.count_program_qubit):
            final_cirq_mapping[self.map_to_cirq_qubit[
                final_mapping[i]]] = self.map_program_qubit_to[i]

        return [circuit, final_cirq_mapping]
Пример #2
0
def mps_operation_from_gate_operation(
        gate_operation: cirq.GateOperation,
        qudit_to_index_map: Dict[cirq.Qid, int]) -> MPSOperation:
    """Constructs an MPS Operation from a gate operation.

    Args:
        gate_operation: A valid cirq.GateOperation or any child class.
        qudit_to_index_map: Dictionary to map qubits to MPS indices.

    Raises:
        CannotConvertToMPSOperation
            If the gate operation does not have a _unitary_ method.
    """
    num_qudits = len(gate_operation.qubits)
    qudit_dimension = 2  # TODO: Check if all Cirq ops are qubit ops
    qudit_indices = tuple(
        [qudit_to_index_map[qudit] for qudit in gate_operation.qubits])

    if not gate_operation._has_unitary_():
        raise CannotConvertToMPSOperation(
            f"Cannot convert operation {gate_operation} into an MPS Operation"
            " because the operation does not have a unitary.")

    tensor = gate_operation._unitary_()
    tensor = np.reshape(tensor, newshape=[qudit_dimension] * 2 * num_qudits)
    node = tn.Node(tensor)
    return MPSOperation(node, qudit_indices, qudit_dimension)
Пример #3
0
    def solve(self):
        """Use the super().solve(...) and output result in Cirq

        Returns:
            circuit: result in Cirq Circuit object
            final__cirq_mapping: from input Cirq qubit to Cirq qubit
            objective_value: depth/#swap/fidelity depending on setting

        Note:
            final_mapping (returned by super().solve(...)): 
                logical qubit index |-> physical qubit index
            map_to_physical_qubit: qubit index |-> Cirq qubit
            So the final mapping should be m(i) |-> m(f(i))
        """

        (result_depth, list_scheduled_gate_name, list_scheduled_gate_qubits,
         final_mapping, objective_value) = super().solve(output_mode="IR")

        # constructing the output Cirq Circuit object
        circuit = Circuit()
        for t in range(result_depth):
            moment_with_swap = []
            for i, qubits in enumerate(list_scheduled_gate_qubits[t]):
                if len(qubits) == 1:
                    moment_with_swap.append(
                        GateOperation(
                            list_scheduled_gate_name[t][i],
                            (self.map_to_physical_qubit[qubits[0]], )))
                else:
                    if list_scheduled_gate_name[t][i] == "SWAP":
                        moment_with_swap.append(
                            GateOperation(
                                SWAP, (self.map_to_physical_qubit[qubits[0]],
                                       self.map_to_physical_qubit[qubits[1]])))
                    else:
                        op_tmp = list_scheduled_gate_name[t][i]
                        if list_scheduled_gate_name[t][i] == "cx":
                            op_tmp = CNOT
                        moment_with_swap.append(
                            GateOperation(
                                op_tmp,
                                (self.map_to_physical_qubit[qubits[0]],
                                 self.map_to_physical_qubit[qubits[1]])))
            circuit.append(moment_with_swap)

        final_cirq_mapping = dict()
        for i in range(self.count_program_qubit):
            final_cirq_mapping[ self.map_to_physical_qubit[i] ] = \
                self.map_to_physical_qubit[ final_mapping[i] ]

        return [circuit, final_cirq_mapping, objective_value]
Пример #4
0
def test_maps_cz_gate(qubit_1, qubit_2):
    operation = GateOperation(CZPowGate(), [qubit_1, qubit_2])
    mapped = map_operation(operation)
    expected = Instruction(name='cz',
                           qubits=[str(qubit_1), str(qubit_2)],
                           args={})
    assert expected == mapped
Пример #5
0
def test_maps_to_phased_rx(qubit_1, gate, expected_angle, expected_phase):
    operation = GateOperation(gate, [qubit_1])
    mapped = map_operation(operation)
    assert mapped.name == 'phased_rx'
    assert mapped.qubits == [str(qubit_1)]
    # The unit for angle and phase is full turns
    assert mapped.args['angle_t'] == expected_angle
    assert mapped.args['phase_t'] == expected_phase
Пример #6
0
def test_maps_measurement_gate(qubit_1):
    key = 'test measurement'
    operation = GateOperation(MeasurementGate(1, key), [qubit_1])
    mapped = map_operation(operation)
    expected = Instruction(name='measurement',
                           qubits=[str(qubit_1)],
                           args={'key': key})
    assert expected == mapped
Пример #7
0
def test_raises_error_for_non_trivial_invert_mask(qubit_1, qubit_2):
    operation = GateOperation(
        MeasurementGate(2, 'measurement key', invert_mask=(True, False)),
        [qubit_1, qubit_2])
    with pytest.raises(OperationNotSupportedError):
        map_operation(operation)
Пример #8
0
def test_raises_error_for_general_cz_pow_gate(qubit_1, qubit_2):
    operation = GateOperation(CZPowGate(exponent=0.5), [qubit_1, qubit_2])
    with pytest.raises(OperationNotSupportedError):
        map_operation(operation)
Пример #9
0
def test_raises_error_for_unsupported_operation(qubit_1):
    operation = GateOperation(ZPowGate(), [qubit_1])
    with pytest.raises(OperationNotSupportedError):
        map_operation(operation)