Пример #1
0
    def test_serialize_deserialize_paulisum_consistency(self, sum_proto_pair):
        """Serialize and deserialize and ensure nothing changed."""
        self.assertEqual(
            serializer.serialize_paulisum(
                serializer.deserialize_paulisum(sum_proto_pair[1])),
            sum_proto_pair[1])

        self.assertEqual(
            serializer.deserialize_paulisum(
                serializer.serialize_paulisum(sum_proto_pair[0])),
            sum_proto_pair[0])
Пример #2
0
def _sample_expectation_worker_func(indices, programs, params, ops, n_samples):
    x_np = _convert_simple_view_to_np(INFO_DICT['arr'], np.float32,
                                      INFO_DICT['shape'])
    simulator = INFO_DICT['sim']

    # TODO: remove this when picklable.
    for i in range(len(ops)):
        for j in range(len(ops[i])):
            ops[i][j] = serializer.deserialize_paulisum(ops[i][j])

    for i, index_tuple in enumerate(indices):
        batch_index = index_tuple[0]
        op_index = index_tuple[1]
        # (#679) Just ignore empty programs.
        if len(programs[batch_index].all_qubits()) == 0:
            continue
        circuit = cirq.resolve_parameters(programs[batch_index],
                                          params[batch_index])

        sampler = TFQPauliSumCollector(
            circuit,
            ops[batch_index][op_index],
            samples_per_term=n_samples[batch_index][op_index])

        asyncio.set_event_loop(asyncio.new_event_loop())
        sampler.collect(simulator, concurrency=1)
        result = sampler.estimated_energy().real

        _pointwise_update_simple_np(x_np, batch_index, op_index, result)
Пример #3
0
def _analytical_expectation_worker_func(indices, programs, params, ops):
    """Compute the expectation of the op[batch_index], w.r.t
    circuit[batch_index] where batch_index is calculated from indices."""
    x_np = _convert_simple_view_to_np(INFO_DICT['arr'], np.float32,
                                      INFO_DICT['shape'])
    simulator = INFO_DICT['sim']

    # TODO: remove this when picklable.
    for i in range(len(ops)):
        for j in range(len(ops[i])):
            ops[i][j] = serializer.deserialize_paulisum(ops[i][j])

    old_batch_index = -2
    state = -1
    for i, index_tuple in enumerate(indices):
        batch_index = index_tuple[0]
        op_index = index_tuple[1]
        # (#679) Just ignore empty programs.
        if len(programs[batch_index].all_qubits()) == 0:
            continue

        if old_batch_index != batch_index:
            # must compute a new state vector.
            qubit_oder = dict(
                zip(sorted(programs[batch_index].all_qubits()),
                    list(range(len(programs[batch_index].all_qubits())))))
            state = simulator.simulate(programs[batch_index],
                                       params[batch_index])

        result = INFO_DICT['post_process'](ops[batch_index][op_index], state,
                                           qubit_oder)
        _pointwise_update_simple_np(x_np, batch_index, op_index, result)
        old_batch_index = batch_index
Пример #4
0
 def test_serialize_deserialize_identity(self):
     """Confirm that identity gates can be serialized and deserialized."""
     q0 = cirq.GridQubit(0, 0)
     q1 = cirq.GridQubit(0, 1)
     paulisum_with_identity = cirq.PauliSum.from_pauli_strings([
         cirq.PauliString(cirq.I(q0)),
         cirq.PauliString(cirq.Z(q0), cirq.Z(q1)),
     ])
     self.assertEqual(
         paulisum_with_identity,
         serializer.deserialize_paulisum(
             serializer.serialize_paulisum(paulisum_with_identity)))
Пример #5
0
def _parse_single(item):
    try:
        if b'tfq_gate_set' in item:
            # Return a circuit parsing
            obj = cirq.google.api.v2.program_pb2.Program()
            obj.ParseFromString(item)
            out = serializer.deserialize_circuit(obj)
            return out

        # Return a PauliSum parsing.
        obj = pauli_sum_pb2.PauliSum()
        obj.ParseFromString(item)
        out = serializer.deserialize_paulisum(obj)
        return out
    except Exception:
        raise TypeError('Error decoding item: ' + str(item))
Пример #6
0
 def test_deserialize_paulisum_simple(self, sum_proto_pair):
     """Ensure deserialization is correct."""
     self.assertEqual(serializer.deserialize_paulisum(sum_proto_pair[1]),
                      sum_proto_pair[0])
Пример #7
0
 def test_deserialize_paulisum_wrong_type(self, inp):
     """Attempt to deserialize invalid object types."""
     with self.assertRaises(TypeError):
         serializer.deserialize_paulisum(inp)
Пример #8
0
    def cirq_sampled_expectation(programs, symbol_names, symbol_values,
                                 pauli_sums, num_samples):
        """Calculate the sampled expectation value of circuits wrt some
        operator(s).

        Estimates the expectation value for all the `cirq.PauliSum`s in
        `pauli_sums` on each `cirq.Circuit` in `programs`. Each circuit will
        have the values in `symbol_values` resolved into the symbols in the
        circuit (with the ordering defined by `symbol_names`).

        ```python

        symbol_names = ['a', 'b', 'c']
        programs = tfq.convert_to_tensor(
            [cirq.Circuit(H(q0) ** sympy.Symbol('a'),
                          X(q1) ** sympy.Symbol('b'),
                          Y(q2) ** sympy.Symbol('c'))]
        )

        symbol_values = [[3,2,1]]
        pauli_sums = tfq.convert_to_tensor(
            [1.5 * cirq.Z(q0) * cirq.Z(q1)]
        )
        n_samples = [[100]]

        cirq_sampled_expectation(
            programs, symbol_names, sybmol_values, pauli_sums, n_samples)
        ```

        Would place the values of 3 into the Symbol labeled 'a', 2 into the
        symbol labeled 'b' and 1 into the symbol labeled 'c'. Then it would
        estimate the ZZ expectation on this circuit by draw samples from the
        circuit 100 times.

        Args:
            programs: `tf.Tensor` of strings with shape [batch_size] containing
                the string representations of the circuits to be executed.
            symbol_names: `tf.Tensor` of strings with shape [n_params], which
                is used to specify the order in which the values in
                `symbol_values` should be placed inside of the circuits in
                `programs`.
            symbol_values: `tf.Tensor` of real numbers with shape
                [batch_size, n_params] specifying parameter values to resolve
                into the circuits specified by programs, following the ordering
                dictated by `symbol_names`.
            pauli_sums: `tf.Tensor` of strings with shape [batch_size, n_ops]
                containing the string representation of the operators that will
                be used on all of the circuits in the expectation calculations.
            num_samples: `tf.Tensor` with `n_samples[i][j]` is equal to the
                number of samples to draw in each term of `pauli_sums[i][j]`
                when estimating the expectation.

        Returns:
            `tf.Tensor` with shape [batch_size, n_ops] that holds the
                expectation value for each circuit with each op applied to it
                (after resolving the corresponding parameters in).
        """
        _input_check_helper(programs, symbol_names, symbol_values)
        if not (pauli_sums.dtype == tf.dtypes.string):
            raise TypeError('pauli_sums tensor must be of type string.')
        if not (pauli_sums.shape[0] == programs.shape[0]) or \
            len(pauli_sums.shape) != 2:
            raise TypeError('pauli_sums tensor must have the same batch shape '
                            'as programs tensor.')

        if not (num_samples.dtype == tf.dtypes.int32 or
                num_samples.dtype == tf.dtypes.int64):
            raise TypeError('num_samples tensor must be of type int32 of '
                            'int64.')
        if not (num_samples.shape == pauli_sums.shape):
            raise TypeError('num_samples tensor must have the same shape '
                            'as pauli_sums tensor. got: {} expected: {}'.format(
                                num_samples.shape, pauli_sums.shape))
        if tf.less_equal(num_samples, 0).numpy().any():
            raise TypeError('num_samples contains sample value <= 0.')

        programs, resolvers = _batch_deserialize_helper(programs, symbol_names,
                                                        symbol_values)

        num_samples = num_samples.numpy().tolist()

        sum_inputs = []
        for sub_list in pauli_sums.numpy():
            to_append = []
            for x in sub_list:
                obj = pauli_sum_pb2.PauliSum()
                obj.ParseFromString(x)
                to_append.append(serializer.deserialize_paulisum(obj))
            sum_inputs.append(to_append)

        expectations = batch_util.batch_calculate_sampled_expectation(
            programs, resolvers, sum_inputs, num_samples, sampler)

        return expectations
Пример #9
0
    def cirq_analytical_expectation(programs, symbol_names, symbol_values,
                                    pauli_sums):
        """Calculate the expectation value of circuits wrt some operator(s).

        Calculate the expectation value for all the `cirq.PauliSum`s in
        `pauli_sums` on each `cirq.Circuit` in `programs`. Each circuit will
        have the values in `symbol_values` resolved into the symbols in the
        circuit (with the ordering defined by `symbol_names`).

        ```python

        symbol_names = ['a', 'b', 'c']
        programs = tfq.convert_to_tensor(
            [cirq.Circuit(H(q0) ** sympy.Symbol('a'),
                          X(q1) ** sympy.Symbol('b'),
                          Y(q2) ** sympy.Symbol('c'))]
        )

        symbol_values = [[3,2,1]]
        pauli_sums = tfq.convert_to_tensor(
            [1.5 * cirq.Z(q0) * cirq.Z(q1)]
        )

        cirq_analytical_expectation(
            programs, symbol_names, sybmol_values, pauli_sums)
        ```

        Would place the values of 3 into the Symbol labeled 'a', 2 into the
        symbol labeled 'b' and 1 into the symbol labeled 'c'. Then it would
        calculate the ZZ expectation on this circuit.

        Args:
            programs: `tf.Tensor` of strings with shape [batch_size] containing
                the string representations of the circuits to be executed.
            symbol_names: `tf.Tensor` of strings with shape [n_params], which
                is used to specify the order in which the values in
                `symbol_values` should be placed inside of the circuits in
                `programs`.
            symbol_values: `tf.Tensor` of real numbers with shape
                [batch_size, n_params] specifying parameter values to resolve
                into the circuits specified by programs, following the ordering
                dictated by `symbol_names`.
            pauli_sums: `tf.Tensor` of strings with shape [batch_size, n_ops]
                containing the string representation of the operators that will
                be used on all of the circuits in the expectation calculations.

        Returns:
            `tf.Tensor` with shape [batch_size, n_ops] that holds the
                expectation value for each circuit with each op applied to it
                (after resolving the corresponding parameters in).
        """
        _input_check_helper(programs, symbol_names, symbol_values)
        if not (pauli_sums.dtype == tf.dtypes.string):
            raise TypeError('pauli_sums tensor must be of type string.')
        if not (pauli_sums.shape[0] == programs.shape[0]):
            raise TypeError('pauli_sums tensor must have the same batch shape '
                            'as programs tensor.')

        programs, resolvers = _batch_deserialize_helper(programs, symbol_names,
                                                        symbol_values)

        sum_inputs = []
        for sub_list in pauli_sums.numpy():
            to_append = []
            for x in sub_list:
                obj = pauli_sum_pb2.PauliSum()
                obj.ParseFromString(x)
                to_append.append(serializer.deserialize_paulisum(obj))
            sum_inputs.append(to_append)

        expectations = batch_util.batch_calculate_expectation(
            programs, resolvers, sum_inputs, simulator)

        return expectations