예제 #1
0
    def test_initializer_context_type_error(self):
        focus = (_random_operation(1, 2), _random_operation(1))

        with self.assertRaisesRegex(
                TypeError,
                r'context is not a TransformationContext \(found type: int\)'):
            transform.AttentionCircuit(focus, 42)
예제 #2
0
    def test_initializer_focus_type_error(self, focus, message):
        context = transform.TransformationContext(circuit.Circuit(5, None),
                                                  circuit.Circuit(5, None),
                                                  circuit.Circuit(5, None))

        with self.assertRaisesRegex(TypeError, message):
            transform.AttentionCircuit(focus, context)
예제 #3
0
    def test_initializer_empty_focus_error(self):
        context = transform.TransformationContext(circuit.Circuit(5, None),
                                                  circuit.Circuit(5, None),
                                                  circuit.Circuit(5, None))

        with self.assertRaisesRegex(ValueError, r'focus must not be empty'):
            transform.AttentionCircuit((), context)
예제 #4
0
    def test_initializer_and_getters(self):
        # preparation work
        focus_in = [_random_operation(1, 2)]
        context_in = transform.TransformationContext(circuit.Circuit(5, None),
                                                     circuit.Circuit(5, None),
                                                     circuit.Circuit(5, None))
        locations_in = (0, )
        perform_rule = lambda operation_in: [operation_in]
        rule_id = object()

        # initialize the PointTransformation
        transformation = transform.PointTransformation(
            attention_circ=transform.AttentionCircuit(focus=focus_in,
                                                      context=context_in,
                                                      locations=locations_in),
            perform_rule=perform_rule,
            rule_id=rule_id)

        # check type and value transformation.focus()
        focus_out = transformation.focus()
        self.assertIs(type(focus_out), tuple)
        self.assertTrue(_elementwise_is(focus_out, focus_in))

        # check transformation.context()
        self.assertIs(transformation.context(), context_in)

        # check type and value transformation.locations()
        locations_out = transformation.locations()
        self.assertIs(type(locations_out), tuple)
        self.assertTrue(_elementwise_is(locations_out, locations_in))

        # check transformation.context()
        self.assertIs(transformation.rule_id(), rule_id)
예제 #5
0
    def test_initializer_without_locations_and_getters(self):
        # preparation work
        focus_in = (_random_operation(1, 2), _random_operation(1))
        focus_length = len(focus_in)
        context = transform.TransformationContext(
            circuit.Circuit(5, [
                _random_operation(2),
                _random_operation(3),
                _random_operation(4)
            ]), circuit.Circuit(5, [_random_operation(0)]),
            circuit.Circuit(5, [_random_operation(0),
                                _random_operation(1, 2)]))

        # construct the AttentionCircuit
        att_circ = transform.AttentionCircuit(focus_in,
                                              context,
                                              locations=None)

        # check type and value for att_circ.focus()
        focus_out = att_circ.focus()
        self.assertIs(type(focus_out), tuple)
        self.assertTrue(_elementwise_is(focus_out, focus_in))

        # check att_circ.context()
        self.assertIs(att_circ.context(), context)

        # check that att_circ.locations() is None
        self.assertIsNone(att_circ.locations())

        # check type and value for len(att_circ)
        length = len(att_circ)
        self.assertIs(type(length), int)
        self.assertEqual(length, focus_length)
예제 #6
0
    def test_perform(self):
        # preparation work
        num_qubits = 5

        operation_before1 = _random_operation(0)
        operation_before2 = _random_operation(1)
        operation_before3 = _random_operation(2)
        operation_between1 = _random_operation(0)
        operation_between2 = _random_operation(1)
        operation_after = _random_operation(1)

        operation_in1 = _random_operation(1)
        operation_in2 = _random_operation(1)
        operation_in3 = _random_operation(1)
        operation_in4 = _random_operation(1)
        operation_out1 = _random_operation(1)
        operation_out2 = _random_operation(1)
        operation_out3 = _random_operation(1)

        # define the transformation rule
        def perform_rule(operations_in):
            # check type and value for operations_in
            self.assertIs(type(operations_in), tuple)
            self.assertTrue(
                _elementwise_is(operations_in, [
                    operation_in1, operation_in2, operation_in3, operation_in4
                ]))

            # return the modified operations
            return [operation_out1, operation_out2, operation_out3]

        # initialize the PointTransformation
        transformation = transform.GroupTransformation(
            attention_circ=transform.AttentionCircuit(
                focus=[
                    operation_in1, operation_in2, operation_in3, operation_in4
                ],
                context=transform.TransformationContext(
                    circuit.Circuit(num_qubits, [
                        operation_before1, operation_before2, operation_before3
                    ]),
                    circuit.Circuit(num_qubits,
                                    [operation_between1, operation_between2]),
                    circuit.Circuit(num_qubits, [operation_after]))),
            perform_rule=perform_rule,
            rule_id=None)

        # call the method to be tested
        circ_out = transformation.perform()

        # check type for circ_out
        self.assertIs(type(circ_out), circuit.Circuit)

        # check the value for circ_out
        self.assertTrue(
            _elementwise_is(circ_out.get_operation_sequence(), [
                operation_before1, operation_before2, operation_before3,
                operation_out1, operation_out2, operation_out3,
                operation_between1, operation_between2, operation_after
            ]))
예제 #7
0
    def test_initializer_locations_type_error(self, locations, message):
        focus = (_random_operation(1, 2), _random_operation(1))
        context = transform.TransformationContext(circuit.Circuit(5, None),
                                                  circuit.Circuit(5, None),
                                                  circuit.Circuit(5, None))

        with self.assertRaisesRegex(TypeError, message):
            transform.AttentionCircuit(focus, context, locations=locations)
예제 #8
0
def _positive_example_circuit(*segments_and_operations):
    operations = []
    segments = {'focus': [], 'before': [], 'between': [], 'after': []}
    max_qubit = 0

    for location, (segment_tag,
                   operation) in enumerate(segments_and_operations):
        operations.append(operation)
        segments[segment_tag].append(location)
        max_qubit = np.maximum(max_qubit, max(operation.get_qubits()))

    circ = circuit.Circuit(max_qubit + 1, operations)

    # <checking that the example circuit makes sense>
    assert len(segments['focus']) == 2
    location_first, location_second = segments['focus']  # length checked in previous line, so pylint: disable=unbalanced-tuple-unpacking

    assert all(location_before < location_second
               for location_before in segments['before'])
    assert all(location_first < location_between < location_second
               for location_between in segments['between'])
    assert all(location_after > location_first
               for location_after in segments['after'])

    pool_to_the_left = [
        location_before for location_before in segments['before']
        if location_before > location_first
    ]
    pool_to_the_right = [
        location_after for location_after in segments['after']
        if location_after < location_second
    ]

    assert all(circ[location_second].commutes_trivially_with(circ[location])
               for location in segments['between'] + pool_to_the_right)
    assert all(circ[location_first].commutes_trivially_with(circ[location])
               for location in pool_to_the_left + segments['between'])
    assert all(loc0 < loc1 or circ[loc0].commutes_trivially_with(circ[loc1])
               for loc0, loc1 in itertools.product(pool_to_the_left,
                                                   segments['between']))
    assert all(loc0 < loc1 or circ[loc0].commutes_trivially_with(circ[loc1])
               for loc0, loc1 in itertools.product(pool_to_the_left,
                                                   pool_to_the_right))
    assert all(loc0 < loc1 or circ[loc0].commutes_trivially_with(circ[loc1])
               for loc0, loc1 in itertools.product(segments['between'],
                                                   pool_to_the_right))
    # </checking that the example circuit makes sense>

    return circ, transform.AttentionCircuit(
        focus=circ[segments['focus']].get_operation_sequence(),
        context=transform.TransformationContext(
            before=circ[segments['before']],
            between=circ[segments['between']],
            after=circ[segments['after']]),
        locations=segments['focus'])
예제 #9
0
    def test_initializer_focus_size_error(self):
        attention_circ = transform.AttentionCircuit(
            focus=[_random_operation(2)],
            context=transform.TransformationContext(circuit.Circuit(5, None),
                                                    circuit.Circuit(5, None),
                                                    circuit.Circuit(5, None)))
        perform_rule = lambda operation_in: [operation_in]

        with self.assertRaisesRegex(
                ValueError,
                r'focus of attention_circ for PairTransformation must have size 2'
                r' \(found: 1\)'):
            transform.PairTransformation(attention_circ, perform_rule, None)
예제 #10
0
    def test_initializer_redundant_transformation_error(self):
        attention_circ = transform.AttentionCircuit(
            focus=[_random_operation(2, 3),
                   _random_operation(5)],
            context=transform.TransformationContext(circuit.Circuit(5, None),
                                                    circuit.Circuit(5, None),
                                                    circuit.Circuit(5, None)))
        perform_rule = lambda operation_in: [operation_in]

        with self.assertRaisesRegex(
                ValueError,
                r'transformation redundant because operations trivially commute'
        ):
            transform.PairTransformation(attention_circ, perform_rule, None)
예제 #11
0
    def test_initializer_locations_length_error(self):
        focus = (_random_operation(1, 2), _random_operation(1))
        context = transform.TransformationContext(
            circuit.Circuit(5, [
                _random_operation(2),
                _random_operation(3),
                _random_operation(4)
            ]), circuit.Circuit(5, [_random_operation(0)]),
            circuit.Circuit(5, [_random_operation(0),
                                _random_operation(1, 2)]))

        with self.assertRaisesRegex(
                ValueError,
                r'inconsistent lengths for focus and locations: 2 vs. 1'):
            transform.AttentionCircuit(focus, context, locations=(3, ))
예제 #12
0
  def test_perform(self):
    # preparation work
    num_qubits = 5

    operation_before1 = _random_operation(0)
    operation_before2 = _random_operation(1)
    operation_before3 = _random_operation(2)
    operation_between1 = _random_operation(0)
    operation_between2 = _random_operation(1)
    operation_after = _random_operation(1)

    operation_in1 = _random_operation(1)
    operation_in2 = _random_operation(1)
    operations_out_first1 = _random_operation(1)
    operations_out_first2 = _random_operation(1)
    operations_out_second1 = _random_operation(1)
    operations_out_second2 = _random_operation(1)
    operations_out_second3 = _random_operation(1)

    # define the transformation rule
    def perform_rule(operation_first, operation_second):
      # check operation_first and operation_second
      self.assertIs(operation_first, operation_in1)
      self.assertIs(operation_second, operation_in2)

      # return the modified operations
      operations_out_first = [
          operations_out_first1,
          operations_out_first2
      ]
      operations_out_second = [
          operations_out_second1,
          operations_out_second2,
          operations_out_second3
      ]
      return operations_out_first, operations_out_second

    # initialize the PointTransformation
    transformation = transform.PairTransformation(
        attention_circ=transform.AttentionCircuit(
            focus=[operation_in1, operation_in2],
            context=transform.TransformationContext(
                circuit.Circuit(num_qubits, [
                    operation_before1,
                    operation_before2,
                    operation_before3
                ]),
                circuit.Circuit(num_qubits, [
                    operation_between1,
                    operation_between2
                ]),
                circuit.Circuit(num_qubits, [
                    operation_after
                ])
            )
        ),
        perform_rule=perform_rule,
        rule_id=None
    )

    # call the method to be tested
    circ_out = transformation.perform()

    # check type for circ_out
    self.assertIs(type(circ_out), circuit.Circuit)

    # check the value for circ_out
    self.assertTrue(_elementwise_is(
        circ_out.get_operation_sequence(),
        [
            operation_before1,
            operation_before2,
            operation_before3,
            operations_out_first1,
            operations_out_first2,
            operation_between1,
            operation_between2,
            operations_out_second1,
            operations_out_second2,
            operations_out_second3,
            operation_after
        ]
    ))