-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Add Counts object #4501
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
Merged
Merged
Add Counts object #4501
Changes from all commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
9740b29
Add Counts object
mtreinish 46254a0
Fix docs build
mtreinish 57c251c
Fix lint
mtreinish 10a7b7b
Merge branch 'master' into add-counts-object
mtreinish f433cbd
Add missing test file
mtreinish b72a2e1
Merge branch 'add-counts-object' of github.com:mtreinish/qiskit-core …
mtreinish 47d1484
Merge branch 'master' into add-counts-object
mtreinish 9d0d9af
Merge branch 'master' into add-counts-object
mtreinish a4e5ce5
Switch custom exception class to QiskitError
mtreinish 3a07fc7
Cleanup release note
mtreinish 0525230
Add comment about dict subclassing
mtreinish aea7d97
Merge branch 'add-counts-object' of github.com:mtreinish/qiskit-core …
mtreinish 442db9f
Tweak comment wording slightly
mtreinish 4bdd9a4
Merge branch 'master' into add-counts-object
mtreinish 8c73ea2
Merge branch 'master' into add-counts-object
mtreinish f3eaf08
Add support for int and binary input keys and handle qudits
mtreinish a51dd21
Merge branch 'master' into add-counts-object
mtreinish c249b64
Fix tests
mtreinish 0612298
Fix lint
mtreinish 5a09207
Handle 0b prefixed binary strings
mtreinish e0c1e8c
Update init docs
mtreinish 3acb00b
Fix docs again
mtreinish c870623
Add tests for 0b prefixed input
mtreinish b299e2e
Merge branch 'master' into add-counts-object
mtreinish 07b0397
Merge branch 'master' into add-counts-object
mtreinish f0ffda3
Merge branch 'master' into add-counts-object
mtreinish c1d7860
Remove metadata from Counts object
mtreinish b6a5e05
Use Counts instead of dict for Results.get_counts() output
mtreinish f53cede
Merge branch 'master' into add-counts-object
mtreinish 91cf8fb
Remove other circuit level metadata
mtreinish c3f1508
Merge branch 'master' into add-counts-object
mtreinish dc1efdc
Update results to not include removed metadata
mtreinish 6c95b65
Fix tests
mtreinish 791c1e7
Really remove metadata from class
mtreinish cef4a2a
Merge branch 'master' into add-counts-object
mtreinish 96b1672
Merge branch 'master' into add-counts-object
mtreinish 03da057
Merge branch 'master' into add-counts-object
mtreinish 5b0c74c
Merge branch 'master' into add-counts-object
1ucian0 e142763
Merge branch 'master' into add-counts-object
1ucian0 31009d2
Merge branch 'master' into add-counts-object
mergify[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,175 @@ | ||
| # -*- coding: utf-8 -*- | ||
|
|
||
| # This code is part of Qiskit. | ||
| # | ||
| # (C) Copyright IBM 2020. | ||
| # | ||
| # This code is licensed under the Apache License, Version 2.0. You may | ||
| # obtain a copy of this license in the LICENSE.txt file in the root directory | ||
| # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
| # | ||
| # Any modifications or derivative works of this code must retain this | ||
| # copyright notice, and modified files need to carry a notice indicating | ||
| # that they have been altered from the originals. | ||
|
|
||
| """A container class for counts from a circuit execution.""" | ||
|
|
||
| import re | ||
|
|
||
| from qiskit.result import postprocess | ||
| from qiskit import exceptions | ||
|
|
||
|
|
||
| # NOTE: A dict subclass should not overload any dunder methods like __getitem__ | ||
| # this can cause unexpected behavior and issues as the cPython dict | ||
| # implementation has many standard methods in C for performance and the dunder | ||
| # methods are not always used as expected. For example, update() doesn't call | ||
| # __setitem__ so overloading __setitem__ would not always provide the expected | ||
| # result | ||
| class Counts(dict): | ||
| """A class to store a counts result from a circuit execution.""" | ||
|
|
||
| def __init__(self, data, time_taken=None, creg_sizes=None, | ||
| memory_slots=None): | ||
| """Build a counts object | ||
|
|
||
| Args: | ||
| data (dict): The dictionary input for the counts. Where the keys | ||
| represent a measured classical value and the value is an | ||
| integer the number of shots with that result. | ||
| The keys can be one of several formats: | ||
|
|
||
| * A hexademical string of the form ``"0x4a"`` | ||
| * A bit string prefixed with ``0b`` for example ``'0b1011'`` | ||
| * A bit string formatted across register and memory slots. | ||
| For example, ``'00 10'``. | ||
| * A dit string, for example ``'02'``. Note for objects created | ||
| with dit strings the ``creg_sizes``and ``memory_slots`` | ||
| kwargs don't work and :meth:`hex_outcomes` and | ||
| :meth:`int_outcomes` also do not work. | ||
|
|
||
| time_taken (float): The duration of the experiment that generated | ||
|
mtreinish marked this conversation as resolved.
|
||
| the counts | ||
| creg_sizes (list): a nested list where the inner element is a list | ||
| of tuples containing both the classical register name and | ||
| classical register size. For example, | ||
| ``[('c_reg', 2), ('my_creg', 4)]``. | ||
| memory_slots (int): The number of total ``memory_slots`` in the | ||
| experiment. | ||
| Raises: | ||
| TypeError: If the input key type is not an int or string | ||
| QiskitError: If a dit string key is input with creg_sizes and/or | ||
| memory_slots | ||
| """ | ||
| bin_data = None | ||
| data = dict(data) | ||
| first_key = next(iter(data.keys())) | ||
| if isinstance(first_key, int): | ||
| self.int_raw = data | ||
| self.hex_raw = { | ||
| hex(key): value for key, value in self.int_raw.items()} | ||
| elif isinstance(first_key, str): | ||
| if first_key.startswith('0x'): | ||
| self.hex_raw = data | ||
| self.int_raw = { | ||
| int(key, 0): value for key, value in self.hex_raw.items()} | ||
| elif first_key.startswith('0b'): | ||
| self.int_raw = { | ||
| int(key, 0): value for key, value in data.items()} | ||
| self.hex_raw = { | ||
| hex(key): value for key, value in self.int_raw.items()} | ||
| else: | ||
| if not creg_sizes and not memory_slots: | ||
| self.hex_raw = None | ||
| self.int_raw = None | ||
| bin_data = data | ||
| else: | ||
| bitstring_regex = re.compile(r'^[01\s]+$') | ||
| hex_dict = {} | ||
| int_dict = {} | ||
| for bitstring, value in data.items(): | ||
| if not bitstring_regex.search(bitstring): | ||
| raise exceptions.QiskitError( | ||
| 'Counts objects with dit strings do not ' | ||
| 'currently support dit string formatting parameters ' | ||
| 'creg_sizes or memory_slots') | ||
| int_key = int(bitstring.replace(" ", ""), 2) | ||
| int_dict[int_key] = value | ||
| hex_dict[hex(int_key)] = value | ||
| self.hex_raw = hex_dict | ||
| self.int_raw = int_dict | ||
| else: | ||
| raise TypeError("Invalid input key type %s, must be either an int " | ||
| "key or string key with hexademical value or bit string") | ||
| header = {} | ||
| self.creg_sizes = creg_sizes | ||
| if self.creg_sizes: | ||
| header['creg_sizes'] = self.creg_sizes | ||
| self.memory_slots = memory_slots | ||
| if self.memory_slots: | ||
| header['memory_slots'] = self.memory_slots | ||
| if not bin_data: | ||
| bin_data = postprocess.format_counts(self.hex_raw, header=header) | ||
| super().__init__(bin_data) | ||
| self.time_taken = time_taken | ||
|
|
||
| def most_frequent(self): | ||
| """Return the most frequent count | ||
|
|
||
| Returns: | ||
| str: The bit string for the most frequent result | ||
| Raises: | ||
| QiskitError: when there is >1 count with the same max counts | ||
| """ | ||
| max_value = max(self.values()) | ||
| max_values_counts = [x[0] for x in self.items() if x[1] == max_value] | ||
| if len(max_values_counts) != 1: | ||
| raise exceptions.QiskitError( | ||
| "Multiple values have the same maximum counts: %s" % | ||
| ','.join(max_values_counts)) | ||
| return max_values_counts[0] | ||
|
|
||
| def hex_outcomes(self): | ||
| """Return a counts dictionary with hexademical string keys | ||
|
|
||
| Returns: | ||
| dict: A dictionary with the keys as hexadecimal strings instead of | ||
| bitstrings | ||
| Raises: | ||
| QiskitError: If the Counts object contains counts for dit strings | ||
| """ | ||
| if self.hex_raw: | ||
| return {key.lower(): value for key, value in self.hex_raw.items()} | ||
| else: | ||
| bitstring_regex = re.compile(r'^[01\s]+$') | ||
| out_dict = {} | ||
| for bitstring, value in self.items(): | ||
| if not bitstring_regex.search(bitstring): | ||
| raise exceptions.QiskitError( | ||
| 'Counts objects with dit strings do not ' | ||
| 'currently support conversion to hexadecimal') | ||
| int_key = int(bitstring.replace(" ", ""), 2) | ||
| out_dict[hex(int_key)] = value | ||
| return out_dict | ||
|
|
||
| def int_outcomes(self): | ||
| """Build a counts dictionary with integer keys instead of count strings | ||
|
|
||
| Returns: | ||
| dict: A dictionary with the keys as integers instead of bitstrings | ||
| Raises: | ||
| QiskitError: If the Counts object contains counts for dit strings | ||
| """ | ||
| if self.int_raw: | ||
| return self.int_raw | ||
| else: | ||
| bitstring_regex = re.compile(r'^[01\s]+$') | ||
| out_dict = {} | ||
| for bitstring, value in self.items(): | ||
| if not bitstring_regex.search(bitstring): | ||
| raise exceptions.QiskitError( | ||
| 'Counts objects with dit strings do not ' | ||
| 'currently support conversion to integer') | ||
| int_key = int(bitstring.replace(" ", ""), 2) | ||
| out_dict[int_key] = value | ||
| return out_dict | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| --- | ||
| features: | ||
| - | | ||
| A new class, :class:`qiskit.result.Counts` has been added. This class | ||
| is a subclass of ``dict`` and can be interacted with like any other | ||
| dictionary. But, it includes helper methods and attributes for dealing | ||
| with counts results from experiments and also handles post processing | ||
| and formatting of binary strings at object initialization. A ``Counts`` | ||
| object can be created by passing a dictionary of counts with the keys | ||
| being hexademical strings of the form ``'0x4a'`` and the value is the | ||
| number of shots. For example:: | ||
|
|
||
| from qiskit.result import Counts | ||
|
|
||
| counts = Counts({"0x0': 1, '0x1', 3, '0x2': 1020}) | ||
|
|
||
| A ``Counts`` object can be treated as a dictionary of binary string keys | ||
| like the output of :meth:`qiskit.result.Result.get_counts`. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.