Example #1
0
def test_param_hash():
    params1 = [('beta', 1.23), ('gamma', 4.56)]
    params2 = [('beta', 1.23), ('gamma', 4.56)]
    params3 = [('beta', 1.24), ('gamma', 4.57)]
    params4 = [('beta', 1.23 + 0.01j), ('gamma', 4.56 + 0.01j)]
    params5 = [('beta', 1.23 + 0.01j), ('gamma', 4.56 + 0.01j)]
    assert _hashable_param(params1) == _hashable_param(params1)
    assert hash(_hashable_param(params1)) == hash(_hashable_param(params1))
    assert _hashable_param(params1) == _hashable_param(params2)
    assert hash(_hashable_param(params1)) == hash(_hashable_param(params2))
    assert _hashable_param(params1) != _hashable_param(params3)
    assert hash(_hashable_param(params1)) != hash(_hashable_param(params3))
    assert _hashable_param(params1) != _hashable_param(params4)
    assert hash(_hashable_param(params1)) != hash(_hashable_param(params4))
    assert _hashable_param(params4) == _hashable_param(params5)
    assert hash(_hashable_param(params4)) == hash(_hashable_param(params5))
Example #2
0
    def sample_expectation_values(
        self,
        program: 'cirq.AbstractCircuit',
        observables: Union['cirq.PauliSumLike', List['cirq.PauliSumLike']],
        *,
        num_samples: int,
        params: 'cirq.Sweepable' = None,
        permit_terminal_measurements: bool = False,
    ) -> Sequence[Sequence[float]]:
        """Calculates estimated expectation values from samples of a circuit.

        Please see also `cirq.work.observable_measurement.measure_observables`
        for more control over how to measure a suite of observables.

        This method can be run on any device or simulator that supports circuit sampling. Compare
        with `simulate_expectation_values` in simulator.py, which is limited to simulators
        but provides exact results.

        Args:
            program: The circuit which prepares a state from which we sample expectation values.
            observables: A list of observables for which to calculate expectation values.
            num_samples: The number of samples to take. Increasing this value increases the
                statistical accuracy of the estimate.
            params: Parameters to run with the program.
            permit_terminal_measurements: If the provided circuit ends in a measurement, this
                method will generate an error unless this is set to True. This is meant to
                prevent measurements from ruining expectation value calculations.

        Returns:
            A list of expectation-value lists. The outer index determines the sweep, and the inner
            index determines the observable. For instance, results[1][3] would select the fourth
            observable measured in the second sweep.

        Raises:
            ValueError: If the number of samples was not positive, if empty observables were
                supplied, or if the provided circuit has terminal measurements and
                `permit_terminal_measurements` is true.
        """
        if num_samples <= 0:
            raise ValueError(
                f'Expectation values require at least one sample. Received: {num_samples}.'
            )
        if not observables:
            raise ValueError('At least one observable must be provided.')
        if not permit_terminal_measurements and program.are_any_measurements_terminal(
        ):
            raise ValueError(
                'Provided circuit has terminal measurements, which may '
                'skew expectation values. If this is intentional, set '
                'permit_terminal_measurements=True.')

        # Wrap input into a list of pauli sum
        pauli_sums: List['cirq.PauliSum'] = (
            [ops.PauliSum.wrap(o) for o in observables] if isinstance(
                observables, List) else [ops.PauliSum.wrap(observables)])
        del observables

        # Flatten Pauli Sum into one big list of Pauli String
        # Keep track of which Pauli Sum each one was from.
        flat_pstrings: List['cirq.PauliString'] = []
        pstring_to_psum_i: Dict['cirq.PauliString', int] = {}
        for psum_i, pauli_sum in enumerate(pauli_sums):
            for pstring in pauli_sum:
                flat_pstrings.append(pstring)
                pstring_to_psum_i[pstring] = psum_i

        # Flatten Circuit Sweep into one big list of Params.
        # Keep track of their indices so we can map back.
        flat_params: List['cirq.ParamDictType'] = [
            pr.param_dict for pr in study.to_resolvers(params)
        ]
        circuit_param_to_sweep_i: Dict[FrozenSet[Tuple[str, Union[int, Tuple[
            int, int]]]], int] = {
                _hashable_param(param.items()): i
                for i, param in enumerate(flat_params)
            }

        obs_meas_results = measure_observables(
            circuit=program,
            observables=flat_pstrings,
            sampler=self,
            stopping_criteria=RepetitionsStoppingCriteria(
                total_repetitions=num_samples),
            readout_symmetrization=False,
            circuit_sweep=params,
            checkpoint=CheckpointFileOptions(checkpoint=False),
        )

        # Results are ordered by how they're grouped. Since we want the (circuit_sweep, pauli_sum)
        # nesting structure, we place the measured values according to the back-mappings we set up
        # above. We also do the sum operation to aggregate multiple PauliString measured values
        # for a given PauliSum.
        nested_results: List[List[float]] = [[0] * len(pauli_sums)
                                             for _ in range(len(flat_params))]
        for res in obs_meas_results:
            param_i = circuit_param_to_sweep_i[_hashable_param(
                res.circuit_params.items())]
            psum_i = pstring_to_psum_i[res.setting.observable]
            nested_results[param_i][psum_i] += res.mean

        return nested_results
def test_param_hash():
    params1 = [
        ('beta', 1.23),
        ('gamma', 4.56),
    ]
    params2 = [
        ('beta', 1.23),
        ('gamma', 4.56),
    ]
    params3 = [
        ('beta', 1.24),
        ('gamma', 4.57),
    ]
    assert _hashable_param(params1) == _hashable_param(params1)
    assert hash(_hashable_param(params1)) == hash(_hashable_param(params1))
    assert _hashable_param(params1) == _hashable_param(params2)
    assert hash(_hashable_param(params1)) == hash(_hashable_param(params2))
    assert _hashable_param(params1) != _hashable_param(params3)
    assert hash(_hashable_param(params1)) != _hashable_param(params3)