Exemple #1
0
 def test_bin_no_prefix_quasi_bin_out(self):
     """Test binary input without a 0b prefix and binary output."""
     qprobs = {
         "000": 3 / 5,
         "001": 1 / 2,
         "010": 7 / 20,
         "011": 1 / 10,
         "100": -11 / 20
     }
     quasi = QuasiDistribution(qprobs)
     self.assertEqual(qprobs, quasi.binary_probabilities())
Exemple #2
0
 def test_known_quasi_conversion(self):
     """Reproduce conversion from Smolin PRL"""
     qprobs = {0: 3 / 5, 1: 1 / 2, 2: 7 / 20, 3: 1 / 10, 4: -11 / 20}
     closest, dist = QuasiDistribution(
         qprobs).nearest_probability_distribution(return_distance=True)
     ans = {0: 9 / 20, 1: 7 / 20, 2: 1 / 5}
     # Check probs are correct
     for key, val in closest.items():
         assert abs(ans[key] - val) < 1e-14
     # Check if distance calculation is correct
     assert abs(dist - sqrt(0.38)) < 1e-14
Exemple #3
0
 def test_hex_quasi_hex_out(self):
     """Test hexadecimal input and hexadecimal output."""
     qprobs = {
         "0x0": 3 / 5,
         "0x1": 1 / 2,
         "0x2": 7 / 20,
         "0x3": 1 / 10,
         "0x4": -11 / 20
     }
     quasi = QuasiDistribution(qprobs)
     self.assertEqual(qprobs, quasi.hex_probabilities())
Exemple #4
0
 def test_known_quasi_conversion(self):
     """Reproduce conversion from Smolin PRL"""
     qprobs = {
         "0": 3 / 5,
         "1": 1 / 2,
         "2": 7 / 20,
         "3": 1 / 10,
         "4": -11 / 20
     }
     closest, dist = QuasiDistribution(
         qprobs).nearest_probability_distribution(return_distance=True)
     ans = {"0": 9 / 20, "1": 7 / 20, "2": 1 / 5}
     # Check probs are correct
     for key, val in closest.items():
         self.assertLess(abs(ans[key] - val), 1e-14)
     # Check if distance calculation is correct
     self.assertLess(abs(dist - sqrt(0.38)), 1e-14)
Exemple #5
0
 def test_hex_quasi_bin_out_padded(self):
     """Test hexadecimal input and binary output, padded with zeros."""
     qprobs = {
         "0x0": 3 / 5,
         "0x1": 1 / 2,
         "0x2": 7 / 20,
         "0x3": 1 / 10,
         "0x4": -11 / 20
     }
     quasi = QuasiDistribution(qprobs)
     expected = {
         "0000": 3 / 5,
         "0001": 1 / 2,
         "0010": 7 / 20,
         "0011": 1 / 10,
         "0100": -11 / 20
     }
     self.assertEqual(expected, quasi.binary_probabilities(num_bits=4))
Exemple #6
0
 def test_bin_quasi_bin_out(self):
     """Test binary input and binary output."""
     qprobs = {
         "0b0": 3 / 5,
         "0b1": 1 / 2,
         "0b10": 7 / 20,
         "0b11": 1 / 10,
         "0b100": -11 / 20
     }
     quasi = QuasiDistribution(qprobs)
     expected = {
         "000": 3 / 5,
         "001": 1 / 2,
         "010": 7 / 20,
         "011": 1 / 10,
         "100": -11 / 20
     }
     self.assertEqual(expected, quasi.binary_probabilities())
Exemple #7
0
 def test_bin_no_prefix_quasi_hex_out(self):
     """Test binary input without a 0b prefix and hexadecimal output."""
     qprobs = {
         "0": 3 / 5,
         "1": 1 / 2,
         "10": 7 / 20,
         "11": 1 / 10,
         "100": -11 / 20
     }
     quasi = QuasiDistribution(qprobs)
     expected = {
         "0x0": 3 / 5,
         "0x1": 1 / 2,
         "0x2": 7 / 20,
         "0x3": 1 / 10,
         "0x4": -11 / 20
     }
     self.assertEqual(expected, quasi.hex_probabilities())
 def test_hex_quasi_bin_out(self):
     """Test hexadecimal input and binary output."""
     qprobs = {
         "0x0": 3 / 5,
         "0x1": 1 / 2,
         "0x2": 7 / 20,
         "0x3": 1 / 10,
         "0x4": -11 / 20
     }
     quasi = QuasiDistribution(qprobs)
     expected = {
         "0": 3 / 5,
         "1": 1 / 2,
         "10": 7 / 20,
         "11": 1 / 10,
         "100": -11 / 20
     }
     self.assertEqual(expected, quasi.binary_probabilities())
Exemple #9
0
    def get_quasiprobabilities(
        self,
        experiment: Union[int, List] = None
    ) -> Union[QuasiDistribution, List[QuasiDistribution]]:
        """Get quasiprobabilites associated with one or more experiments.

        Parameters:
            experiment: Indices of experiments to grab quasiprobabilities from.

        Returns:
            A single distribution or a list of distributions.

        Raises:
            QiskitError: If experiment result doesn't contain quasiprobabilities.
        """
        if experiment is None:
            exp_keys = range(len(self.results))
        else:
            exp_keys = [experiment]  # type: ignore[assignment]

        dict_list = []
        for key in exp_keys:
            if 'quasiprobabilities' in self.data(key).keys():
                shots = self.results[key].shots
                hex_quasi = self.results[key].data.quasiprobabilities
                bit_lenth = len(
                    self.results[key].header.final_measurement_mapping)
                quasi = {}
                for hkey, val in hex_quasi.items():
                    quasi[_hex_to_bin(hkey).zfill(bit_lenth)] = val

                out = QuasiDistribution(quasi, shots)
                out.shots = shots
                dict_list.append(out)
            else:
                raise QiskitError(
                    'No quasiprobabilities for experiment "{}"'.format(
                        repr(key)))

        # Return first item of dict_list if size is 1
        if len(dict_list) == 1:
            return dict_list[0]
        else:
            return dict_list
Exemple #10
0
    def _call(
        self,
        circuits: Sequence[int],
        parameter_values: Sequence[Sequence[float]],
        **run_options,
    ) -> SamplerResult:
        if self._is_closed:
            raise QiskitError("The primitive has been closed.")

        shots = run_options.pop("shots", None)
        seed = run_options.pop("seed", None)
        if seed is None:
            rng = np.random.default_rng()
        elif isinstance(seed, np.random.Generator):
            rng = seed
        else:
            rng = np.random.default_rng(seed)

        # Initialize metadata
        metadata: list[dict[str, Any]] = [{}] * len(circuits)

        bound_circuits = []
        qargs_list = []
        for i, value in zip(circuits, parameter_values):
            if len(value) != len(self._parameters[i]):
                raise QiskitError(
                    f"The number of values ({len(value)}) does not match "
                    f"the number of parameters ({len(self._parameters[i])}).")
            bound_circuit = (self._circuits[i] if len(value) == 0 else
                             self._circuits[i].bind_parameters(
                                 dict(zip(self._parameters[i], value))))
            bound_circuits.append(bound_circuit)
            qargs_list.append(self._qargs_list[i])
        probabilities = [
            Statevector(circ).probabilities(qargs=qargs)
            for circ, qargs in zip(bound_circuits, qargs_list)
        ]
        if shots is not None:
            probabilities = [
                rng.multinomial(shots, probability) / shots
                for probability in probabilities
            ]
            for metadatum in metadata:
                metadatum["shots"] = shots
        quasis = [QuasiDistribution(dict(enumerate(p))) for p in probabilities]

        return SamplerResult(quasis, metadata)
Exemple #11
0
 def test_bin_no_prefix_quasi(self):
     """Test binary input without 0b prefix."""
     qprobs = {
         "0": 3 / 5,
         "1": 1 / 2,
         "10": 7 / 20,
         "11": 1 / 10,
         "100": -11 / 20
     }
     quasi = QuasiDistribution(qprobs)
     self.assertEqual(
         {
             0: 3 / 5,
             1: 1 / 2,
             2: 7 / 20,
             3: 1 / 10,
             4: -11 / 20
         }, quasi)
Exemple #12
0
 def test_bin_quasi_no_0b(self):
     """Test binary input without 0b in front."""
     qprobs = {
         "000": 3 / 5,
         "001": 1 / 2,
         "010": 7 / 20,
         "011": 1 / 10,
         "100": -11 / 20
     }
     quasi = QuasiDistribution(qprobs)
     self.assertEqual(
         {
             0: 3 / 5,
             1: 1 / 2,
             2: 7 / 20,
             3: 1 / 10,
             4: -11 / 20
         }, quasi)
Exemple #13
0
 def test_bin_quasi(self):
     """Test binary input."""
     qprobs = {
         "0b0": 3 / 5,
         "0b1": 1 / 2,
         "0b10": 7 / 20,
         "0b11": 1 / 10,
         "0b100": -11 / 20
     }
     quasi = QuasiDistribution(qprobs)
     self.assertEqual(
         {
             0: 3 / 5,
             1: 1 / 2,
             2: 7 / 20,
             3: 1 / 10,
             4: -11 / 20
         }, quasi)
Exemple #14
0
 def test_hex_quasi(self):
     """Test hexadecimal input."""
     qprobs = {
         "0x0": 3 / 5,
         "0x1": 1 / 2,
         "0x2": 7 / 20,
         "0x3": 1 / 10,
         "0x4": -11 / 20
     }
     quasi = QuasiDistribution(qprobs)
     self.assertEqual(
         {
             0: 3 / 5,
             1: 1 / 2,
             2: 7 / 20,
             3: 1 / 10,
             4: -11 / 20
         }, quasi)
Exemple #15
0
    def __call__(
        self,
        circuit_indices: Sequence[int] | None = None,
        parameter_values: Sequence[Sequence[float]] | Sequence[float]
        | None = None,
        **run_options,
    ) -> SamplerResult:
        if self._is_closed:
            raise QiskitError("The primitive has been closed.")

        if isinstance(parameter_values, np.ndarray):
            parameter_values = parameter_values.tolist()
        if parameter_values and not isinstance(parameter_values[0],
                                               (np.ndarray, Sequence)):
            parameter_values = cast("Sequence[float]", parameter_values)
            parameter_values = [parameter_values]
        if circuit_indices is None:
            circuit_indices = list(range(len(self._circuits)))
        if parameter_values is None:
            parameter_values = [[]] * len(circuit_indices)
        if len(circuit_indices) != len(parameter_values):
            raise QiskitError(
                f"The number of circuit indices ({len(circuit_indices)}) does not match "
                f"the number of parameter value sets ({len(parameter_values)})."
            )

        bound_circuits_qargs = []
        for i, value in zip(circuit_indices, parameter_values):
            if len(value) != len(self._parameters[i]):
                raise QiskitError(
                    f"The number of values ({len(value)}) does not match "
                    f"the number of parameters ({len(self._parameters[i])}).")
            bound_circuits_qargs.append((
                self._circuits[i].bind_parameters(
                    dict(zip(self._parameters[i], value))),
                self._qargs_list[i],
            ))
        probabilities = [
            Statevector(circ).probabilities(qargs=qargs)
            for circ, qargs in bound_circuits_qargs
        ]
        quasis = [QuasiDistribution(dict(enumerate(p))) for p in probabilities]

        return SamplerResult(quasis, [{}] * len(circuit_indices))
Exemple #16
0
 def test_empty(self):
     """Test empty input."""
     quasi = QuasiDistribution({})
     self.assertEqual(quasi, {})
Exemple #17
0
 def test_invalid_key_string(self):
     """Test invalid key string format raises."""
     with self.assertRaises(ValueError):
         QuasiDistribution({"1a2b": 3 / 5})
Exemple #18
0
 def test_invalid_keys(self):
     """Test invalid key type raises."""
     with self.assertRaises(TypeError):
         QuasiDistribution({1 + 2j: 3 / 5})
Exemple #19
0
 def test_empty_bin_out(self):
     """Test empty input with binary output."""
     quasi = QuasiDistribution({})
     self.assertEqual(quasi.binary_probabilities(), {})
Exemple #20
0
 def test_empty_hex_out(self):
     """Test empty input with hexadecimal output."""
     quasi = QuasiDistribution({})
     self.assertEqual(quasi.hex_probabilities(), {})