Skip to content

Commit

Permalink
Force decimals in scientific notation for OpenQASM 2.0 (#6802)
Browse files Browse the repository at this point in the history
* Force decimals in scientific notation for OpenQASM 2.0

- OpenQASM 2.0 grammar requires decimal points in scientific
notation.  For instance, 1e-10 is not allowed according to a
strict interpretation of the grammar.
- This PR forces the formatter to use a decimal when printing
out scientific notation.
  • Loading branch information
dstrain115 authored Nov 20, 2024
1 parent 02f2f84 commit 76125a2
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
11 changes: 10 additions & 1 deletion cirq-core/cirq/protocols/qasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,23 @@ def __init__(
self.qubit_id_map = {} if qubit_id_map is None else qubit_id_map
self.meas_key_id_map = {} if meas_key_id_map is None else meas_key_id_map

def _format_number(self, value) -> str:
"""OpenQASM 2.0 does not support '1e-5' and wants '1.0e-5'"""
s = f'{value}'
if 'e' in s and not '.' in s:
return s.replace('e', '.0e')
return s

def format_field(self, value: Any, spec: str) -> str:
"""Method of string.Formatter that specifies the output of format()."""
if isinstance(value, (float, int)):
if isinstance(value, float):
value = round(value, self.precision)
if spec == 'half_turns':
value = f'pi*{value}' if value != 0 else '0'
value = f'pi*{self._format_number(value)}' if value != 0 else '0'
spec = ''
else:
value = self._format_number(value)
elif isinstance(value, ops.Qid):
value = self.qubit_id_map[value]
elif isinstance(value, str) and spec == 'meas':
Expand Down
12 changes: 12 additions & 0 deletions cirq-core/cirq/protocols/qasm_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,15 @@ def test_qasm():

assert cirq.qasm(ExpectsArgs(), args=cirq.QasmArgs()) == 'text'
assert cirq.qasm(ExpectsArgsQubits(), args=cirq.QasmArgs(), qubits=()) == 'text'


def test_qasm_args_formatting():
args = cirq.QasmArgs()
assert args.format_field(0.01, '') == '0.01'
assert args.format_field(0.01, 'half_turns') == 'pi*0.01'
assert args.format_field(0.00001, '') == '1.0e-05'
assert args.format_field(0.00001, 'half_turns') == 'pi*1.0e-05'
assert args.format_field(1e-10, 'half_turns') == 'pi*1.0e-10'
args = cirq.QasmArgs(precision=6)
assert args.format_field(0.00001234, '') == '1.2e-05'
assert args.format_field(0.00001234, 'half_turns') == 'pi*1.2e-05'

0 comments on commit 76125a2

Please sign in to comment.