-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add detach prefix function * handling of zero, negative, out of range values * add reno * black * update implementation and add precision handling * fix round off error * parameter expression handling * fix import order * multiply-or-divide trick * update logic * Update qiskit/utils/units.py Co-authored-by: Matthew Treinish <mtreinish@kortar.org> * add unit prefix test * Update qiskit/utils/units.py Co-authored-by: Matthew Treinish <mtreinish@kortar.org> Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
- Loading branch information
1 parent
03183d1
commit 1ea5fd9
Showing
5 changed files
with
270 additions
and
11 deletions.
There are no files selected for viewing
This file contains 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 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 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,8 @@ | ||
--- | ||
features: | ||
- | | ||
Add utility function :py:func:`~qiskit.utils.units.detach_prefix` that is a counterpart of | ||
:py:func:`~qiskit.utils.units.apply_prefix`. | ||
The new function returns a tuple of scaled value and prefix from a given float value. | ||
For example, a value ``1.3e8`` will be converted into ``(130, "M")`` that can be | ||
used to display a value in the user friendly format, such as `130 MHz`. |
This file contains 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,13 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2021. | ||
# | ||
# 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. | ||
|
||
"""Qiskit utilities tests.""" |
This file contains 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,133 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2021. | ||
# | ||
# 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. | ||
|
||
"""Test for unit conversion functions.""" | ||
|
||
from ddt import ddt, data | ||
|
||
from qiskit.test import QiskitTestCase | ||
from qiskit.utils import apply_prefix, detach_prefix | ||
|
||
|
||
@ddt | ||
class TestUnitConversion(QiskitTestCase): | ||
"""Test the unit conversion utilities.""" | ||
|
||
def test_apply_prefix(self): | ||
"""Test applying prefix to value.""" | ||
ref_values = [ | ||
([1.0, "THz"], 1e12), | ||
([1.0, "GHz"], 1e9), | ||
([1.0, "MHz"], 1e6), | ||
([1.0, "kHz"], 1e3), | ||
([1.0, "mHz"], 1e-3), | ||
([1.0, "µHz"], 1e-6), | ||
([1.0, "uHz"], 1e-6), | ||
([1.0, "nHz"], 1e-9), | ||
([1.0, "pHz"], 1e-12), | ||
] | ||
|
||
for args, ref_ret in ref_values: | ||
self.assertEqual(apply_prefix(*args), ref_ret) | ||
|
||
def test_not_convert_meter(self): | ||
"""Test not apply prefix to meter.""" | ||
self.assertEqual(apply_prefix(1.0, "m"), 1.0) | ||
|
||
def test_detach_prefix(self): | ||
"""Test detach prefix from the value.""" | ||
ref_values = [ | ||
(1e12, (1.0, "T")), | ||
(1e11, (100.0, "G")), | ||
(1e10, (10.0, "G")), | ||
(1e9, (1.0, "G")), | ||
(1e8, (100.0, "M")), | ||
(1e7, (10.0, "M")), | ||
(1e6, (1.0, "M")), | ||
(1e5, (100.0, "k")), | ||
(1e4, (10.0, "k")), | ||
(1e3, (1.0, "k")), | ||
(100, (100.0, "")), | ||
(10, (10.0, "")), | ||
(1.0, (1.0, "")), | ||
(0.1, (100.0, "m")), | ||
(0.01, (10.0, "m")), | ||
(1e-3, (1.0, "m")), | ||
(1e-4, (100.0, "µ")), | ||
(1e-5, (10.0, "µ")), | ||
(1e-6, (1.0, "µ")), | ||
(1e-7, (100.0, "n")), | ||
(1e-8, (10.0, "n")), | ||
(1e-9, (1.0, "n")), | ||
(1e-10, (100.0, "p")), | ||
(1e-11, (10.0, "p")), | ||
(1e-12, (1.0, "p")), | ||
] | ||
|
||
for arg, ref_rets in ref_values: | ||
self.assertTupleEqual(detach_prefix(arg), ref_rets) | ||
|
||
def test_detach_prefix_with_zero(self): | ||
"""Test detach prefix by input zero.""" | ||
self.assertTupleEqual(detach_prefix(0.0), (0.0, "")) | ||
|
||
def test_detach_prefix_with_negative(self): | ||
"""Test detach prefix by input negative values.""" | ||
self.assertTupleEqual(detach_prefix(-1.234e7), (-12.34, "M")) | ||
|
||
def test_detach_prefix_with_value_too_large(self): | ||
"""Test detach prefix by input too large value.""" | ||
with self.assertRaises(Exception): | ||
self.assertTupleEqual(detach_prefix(1e20), (1e20, "")) | ||
|
||
def test_detach_prefix_with_value_too_small(self): | ||
"""Test detach prefix by input too small value.""" | ||
with self.assertRaises(Exception): | ||
self.assertTupleEqual(detach_prefix(1e-20), (1e-20, "")) | ||
|
||
def test_rounding(self): | ||
"""Test detach prefix with decimal specification.""" | ||
ret = detach_prefix(999_999.991) | ||
self.assertTupleEqual(ret, (999.999991, "k")) | ||
|
||
ret = detach_prefix(999_999.991, decimal=4) | ||
self.assertTupleEqual(ret, (1.0, "M")) | ||
|
||
ret = detach_prefix(999_999.991, decimal=5) | ||
self.assertTupleEqual(ret, (999.99999, "k")) | ||
|
||
@data( | ||
-20.791378538739863, | ||
9.242757760406565, | ||
2.7366806276451543, | ||
9.183776167253349, | ||
7.658091886606501, | ||
-12.21553566621071, | ||
8.914055281578145, | ||
1.2518807770035825, | ||
-6.652899195646036, | ||
-4.647159596697976, | ||
) | ||
def test_get_same_value_after_attach_detach(self, value: float): | ||
"""Test if same value can be obtained.""" | ||
unit = "Hz" | ||
|
||
for prefix in ["P", "T", "G", "k", "m", "µ", "n", "p", "f"]: | ||
scaled_val = apply_prefix(value, prefix + unit) | ||
test_val, ret_prefix = detach_prefix(scaled_val) | ||
self.assertAlmostEqual(test_val, value) | ||
self.assertEqual(prefix, ret_prefix) | ||
|
||
def test_get_symbol_mu(self): | ||
"""Test if µ is returned rather than u.""" | ||
_, prefix = detach_prefix(3e-6) | ||
self.assertEqual(prefix, "µ") |