Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clip probabilities in QuantumState #9762

Merged
merged 12 commits into from
Mar 17, 2023
2 changes: 1 addition & 1 deletion qiskit/primitives/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def _call(
qargs_list.append(self._qargs_list[i])
probabilities = [
Statevector(bound_circuit_to_instruction(circ)).probabilities_dict(
qargs=qargs, decimals=16
qargs=qargs, decimals=16, clip=True
)
for circ, qargs in zip(bound_circuits, qargs_list)
]
Expand Down
4 changes: 4 additions & 0 deletions qiskit/quantum_info/states/densitymatrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,8 @@ def probabilities(self, qargs=None, decimals=None):
if None return for all subsystems (Default: None).
decimals (None or int): the number of decimal places to round
values. If None no rounding is done (Default: None).
clip (bool): if ``True``, clip the probabilities to ``[0, 1]``
to account for possible roundoff errors (Default: ``True``).

Returns:
np.array: The Numpy vector array of probabilities.
Expand Down Expand Up @@ -482,6 +484,8 @@ def probabilities(self, qargs=None, decimals=None):
)
if decimals is not None:
probs = probs.round(decimals=decimals)
if clip:
probs = np.clip(probs, a_min=0, a_max=1)
return probs

def reset(self, qargs=None):
Expand Down
12 changes: 9 additions & 3 deletions qiskit/quantum_info/states/quantum_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def expectation_value(self, oper, qargs=None):
pass

@abstractmethod
def probabilities(self, qargs=None, decimals=None):
def probabilities(self, qargs=None, decimals=None, clip=False):
"""Return the subsystem measurement probability vector.

Measurement probabilities are with respect to measurement in the
Expand All @@ -207,13 +207,15 @@ def probabilities(self, qargs=None, decimals=None):
if None return for all subsystems (Default: None).
decimals (None or int): the number of decimal places to round
values. If None no rounding is done (Default: None).
clip (bool): if ``True``, clip the probabilities to ``[0, 1]``
to account for possible roundoff errors (Default: ``True``).

Returns:
np.array: The Numpy vector array of probabilities.
"""
pass

def probabilities_dict(self, qargs=None, decimals=None):
def probabilities_dict(self, qargs=None, decimals=None, clip=False):
"""Return the subsystem measurement probability dictionary.

Measurement probabilities are with respect to measurement in the
Expand All @@ -229,12 +231,16 @@ def probabilities_dict(self, qargs=None, decimals=None):
if None return for all subsystems (Default: None).
decimals (None or int): the number of decimal places to round
values. If None no rounding is done (Default: None).
clip (bool): if ``True``, clip the probabilities to ``[0, 1]``
to account for possible roundoff errors (Default: ``True``).

Returns:
dict: The measurement probabilities in dict (ket) form.
"""
return self._vector_to_dict(
self.probabilities(qargs=qargs, decimals=decimals), self.dims(qargs), string_labels=True
self.probabilities(qargs=qargs, decimals=decimals, clip=clip),
self.dims(qargs),
string_labels=True,
)

def sample_memory(self, shots, qargs=None):
Expand Down
15 changes: 13 additions & 2 deletions qiskit/quantum_info/states/stabilizerstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@ def probabilities(self, qargs=None, decimals=None):
if None return for all subsystems (Default: None).
decimals (None or int): the number of decimal places to round
values. If None no rounding is done (Default: None).
clip (bool): if ``True``, clip the probabilities to ``[0, 1]``
to account for possible roundoff errors (Default: ``True``).

Returns:
np.array: The Numpy vector array of probabilities.
Expand All @@ -331,9 +333,12 @@ def probabilities(self, qargs=None, decimals=None):
place = int(key, 2)
probs[place] = value

if clip:
probs = np.clip(probs, a_min=0, a_max=1)

return probs

def probabilities_dict(self, qargs=None, decimals=None):
def probabilities_dict(self, qargs=None, decimals=None, clip=False):
"""Return the subsystem measurement probability dictionary.

Measurement probabilities are with respect to measurement in the
Expand All @@ -349,6 +354,8 @@ def probabilities_dict(self, qargs=None, decimals=None):
if None return for all subsystems (Default: None).
decimals (None or int): the number of decimal places to round
values. If None no rounding is done (Default: None).
clip (bool): if ``True``, clip the probabilities to ``[0, 1]``
to account for possible roundoff errors (Default: ``True``).

Returns:
dict: The measurement probabilities in dict (ket) form.
Expand All @@ -366,7 +373,11 @@ def probabilities_dict(self, qargs=None, decimals=None):

if decimals is not None:
for key, value in probs.items():
probs[key] = round(value, decimals)
prob = round(value, decimals)
if clip:
prob = np.clip(prob, a_min=0, a_max=1)
t-imamichi marked this conversation as resolved.
Show resolved Hide resolved

probs[key] = prob

return probs

Expand Down
6 changes: 5 additions & 1 deletion qiskit/quantum_info/states/statevector.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ def expectation_value(self, oper, qargs=None):
conj = self.conjugate()
return np.dot(conj.data, val.data)

def probabilities(self, qargs=None, decimals=None):
def probabilities(self, qargs=None, decimals=None, clip=False):
"""Return the subsystem measurement probability vector.

Measurement probabilities are with respect to measurement in the
Expand All @@ -515,6 +515,8 @@ def probabilities(self, qargs=None, decimals=None):
if None return for all subsystems (Default: None).
decimals (None or int): the number of decimal places to round
values. If None no rounding is done (Default: None).
clip (bool): if ``True``, clip the probabilities to ``[0, 1]``
to account for possible roundoff errors (Default: ``True``).

Returns:
np.array: The Numpy vector array of probabilities.
Expand Down Expand Up @@ -577,6 +579,8 @@ def probabilities(self, qargs=None, decimals=None):
)
if decimals is not None:
probs = probs.round(decimals=decimals)
if clip:
probs = np.clip(probs, a_min=0, a_max=1)
return probs

def reset(self, qargs=None):
Expand Down