• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

qiskit-community / qiskit-algorithms / 15802199099

13 Jun 2025 01:21PM CUT coverage: 90.448%. Remained the same
15802199099

push

github

web-flow
Fix getter/setter type mismatch (#232)

1 of 1 new or added line in 1 file covered. (100.0%)

6401 of 7077 relevant lines covered (90.45%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.67
/qiskit_algorithms/phase_estimators/phase_estimation_result.py
1
# This code is part of a Qiskit project.
2
#
3
# (C) Copyright IBM 2020, 2023.
4
#
5
# This code is licensed under the Apache License, Version 2.0. You may
6
# obtain a copy of this license in the LICENSE.txt file in the root directory
7
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
#
9
# Any modifications or derivative works of this code must retain this
10
# copyright notice, and modified files need to carry a notice indicating
11
# that they have been altered from the originals.
12

13
"""Result of running PhaseEstimation"""
14
from __future__ import annotations
1✔
15
import numpy
1✔
16

17
from qiskit.result import Result
1✔
18
from .phase_estimator import PhaseEstimatorResult
1✔
19

20

21
class PhaseEstimationResult(PhaseEstimatorResult):
1✔
22
    """Store and manipulate results from running `PhaseEstimation`.
23

24
    This class is instantiated by the ``PhaseEstimation`` class, not via user code.
25
    The ``PhaseEstimation`` class generates a list of phases and corresponding weights. Upon
26
    completion it returns the results as an instance of this class. The main method for
27
    accessing the results is `filter_phases`.
28

29
    The canonical phase satisfying the ``PhaseEstimator`` interface, returned by the
30
    attribute `phase`, is the most likely phase.
31
    """
32

33
    def __init__(
1✔
34
        self,
35
        num_evaluation_qubits: int,
36
        circuit_result: Result,
37
        phases: numpy.ndarray | dict[str, float],
38
    ) -> None:
39
        """
40
        Args:
41
            num_evaluation_qubits: number of qubits in phase-readout register.
42
            circuit_result: result object returned by method running circuit.
43
            phases: ndarray or dict of phases and frequencies determined by QPE.
44
        """
45
        super().__init__()
1✔
46

47
        self._phases = phases
1✔
48
        # int: number of qubits in phase-readout register
49
        self._num_evaluation_qubits = num_evaluation_qubits
1✔
50
        self._circuit_result = circuit_result
1✔
51

52
    @property
1✔
53
    def phases(self) -> numpy.ndarray | dict:
1✔
54
        """Return all phases and their frequencies computed by QPE.
55

56
        This is an array or dict whose values correspond to weights on bit strings.
57
        """
58
        return self._phases
1✔
59

60
    @property
1✔
61
    def circuit_result(self) -> Result:
1✔
62
        """Return the result object returned by running the QPE circuit (on hardware or simulator).
63

64
        This is useful for inspecting and troubleshooting the QPE algorithm.
65
        """
66
        return self._circuit_result
×
67

68
    @property
1✔
69
    def phase(self) -> float:
1✔
70
        r"""Return the most likely phase as a number in :math:`[0.0, 1.0)`.
71

72
        1.0 corresponds to a phase of :math:`2\pi`. This selects the phase corresponding
73
        to the bit string with the highest probability. This is the most likely phase.
74
        """
75
        if isinstance(self.phases, dict):
1✔
76
            binary_phase_string = max(self.phases, key=self.phases.get)
1✔
77
        else:
78
            # numpy.argmax ignores complex part of number. But, we take abs anyway
79
            idx = numpy.argmax(abs(self.phases))
×
80
            binary_phase_string = f"{idx:0{self._num_evaluation_qubits}b}"[::-1]
×
81
        phase = _bit_string_to_phase(binary_phase_string)
1✔
82
        return phase
1✔
83

84
    def filter_phases(self, cutoff: float = 0.0, as_float: bool = True) -> dict[str | float, float]:
1✔
85
        """Return a filtered dict of phases (keys) and frequencies (values).
86

87
        Only phases with frequencies (counts) larger than `cutoff` are included.
88
        It is assumed that the `run` method has been called so that the phases have been computed.
89
        When using a noiseless, shot-based simulator to read a single phase that can
90
        be represented exactly by `num_evaluation_qubits`, all the weight will
91
        be concentrated on a single phase. In all other cases, many, or all, bit
92
        strings will have non-zero weight. This method is useful for filtering
93
        out these uninteresting bit strings.
94

95
        Args:
96
            cutoff: Minimum weight of number of counts required to keep a bit string.
97
                The default value is `0.0`.
98
            as_float: If `True`, returned keys are floats in :math:`[0.0, 1.0)`. If `False`
99
                returned keys are bit strings.
100

101
        Returns:
102
            A filtered dict of phases (keys) and frequencies (values).
103
        """
104
        phases: dict[str | float, float]
105
        if isinstance(self.phases, dict):
1✔
106
            counts = self.phases
1✔
107
            if as_float:
1✔
108
                phases = {
1✔
109
                    _bit_string_to_phase(k): counts[k] for k in counts.keys() if counts[k] > cutoff
110
                }
111
            else:
112
                phases = {k: counts[k] for k in counts.keys() if counts[k] > cutoff}
1✔
113

114
        else:
115
            phases = {}
×
116
            for idx, amplitude in enumerate(self.phases):
×
117
                if amplitude > cutoff:
×
118
                    # Each index corresponds to a computational basis state with the LSB rightmost.
119
                    # But, we chose to apply the unitaries such that the phase is recorded
120
                    # in reverse order. So, we reverse the bitstrings here.
121
                    binary_phase_string = numpy.binary_repr(idx, self._num_evaluation_qubits)[::-1]
×
122
                    if as_float:
×
123
                        _key: str | float = _bit_string_to_phase(binary_phase_string)
×
124
                    else:
125
                        _key = binary_phase_string
×
126
                    phases[_key] = amplitude
×
127

128
            phases = _sort_phases(phases)
×
129

130
        return phases
1✔
131

132

133
def _bit_string_to_phase(binary_string: str) -> float:
1✔
134
    """Convert bit string to a normalized phase in :math:`[0,1)`.
135

136
    It is assumed that the bit string is correctly padded and that the order of
137
    the bits has been reversed relative to their order when the counts
138
    were recorded. The LSB is the right most when interpreting the bitstring as
139
    a phase.
140

141
    Args:
142
        binary_string: A string of characters '0' and '1'.
143

144
    Returns:
145
        A phase scaled to :math:`[0,1)`.
146
    """
147
    n_qubits = len(binary_string)
1✔
148
    return int(binary_string, 2) / (2**n_qubits)
1✔
149

150

151
def _sort_phases(phases: dict) -> dict:
1✔
152
    """Sort a dict of bit strings representing phases (keys) and frequencies (values) by bit string.
153

154
    The bit strings are sorted according to increasing phase. This relies on Python
155
    preserving insertion order when building dicts.
156
    """
157
    pkeys = list(phases.keys())
×
158
    pkeys.sort(reverse=False)  # Sorts in order of the integer encoded by binary string
×
159
    phases = {k: phases[k] for k in pkeys}
×
160
    return phases
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc