From af8a7fda740cd6367818488c8fe39886aeff7aad Mon Sep 17 00:00:00 2001 From: Elenbaas Date: Thu, 4 Jul 2024 15:12:38 +0200 Subject: [PATCH 01/13] Add significant digit rounding to Bloch sphere __repr__ --- opensquirrel/ir.py | 11 +++++++++-- test/writer/test_writer.py | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/opensquirrel/ir.py b/opensquirrel/ir.py index 068c91ae..0d7e03e8 100644 --- a/opensquirrel/ir.py +++ b/opensquirrel/ir.py @@ -247,6 +247,9 @@ def get_qubit_operands(self) -> list[Qubit]: class Gate(Statement, ABC): + + _sig_digits_repr = 5 + def __init__( self, generator: Callable[..., Gate] | None = None, @@ -265,7 +268,9 @@ def __eq__(self, other: object) -> bool: @property def name(self) -> str: - return self.generator.__name__ if self.generator else "" + if self.generator: + return self.generator.__name__ + return self.__repr__() @property def is_anonymous(self) -> bool: @@ -309,7 +314,9 @@ def identity(q: Qubit) -> BlochSphereRotation: return BlochSphereRotation(qubit=q, axis=(1, 0, 0), angle=0, phase=0) def __repr__(self) -> str: - return f"BlochSphereRotation({self.qubit}, axis={self.axis}, angle={self.angle}, phase={self.phase})" + sdr = self._sig_digits_repr + return (f"BlochSphereRotation({self.qubit}, axis={self.axis}, angle={round(self.angle, sdr)}," + f" phase={round(self.phase, sdr)})") def __eq__(self, other: object) -> bool: if not isinstance(other, BlochSphereRotation): diff --git a/test/writer/test_writer.py b/test/writer/test_writer.py index c04dc64f..70c7f342 100644 --- a/test/writer/test_writer.py +++ b/test/writer/test_writer.py @@ -50,7 +50,7 @@ def test_anonymous_gate() -> None: qubit[2] q CR(1.234) q[0], q[1] - +BlochSphereRotation(Qubit[0], axis=Axis[0.57735027 0.57735027 0.57735027], angle=1.23, phase=0.0) CR(1.234) q[0], q[1] """ ) From 066c8e88ddd5dd2c61890bbd1d79cf9f95d3dd90 Mon Sep 17 00:00:00 2001 From: Elenbaas Date: Mon, 8 Jul 2024 14:35:12 +0200 Subject: [PATCH 02/13] Output representation of semantic instead of --- opensquirrel/ir.py | 11 +++++----- test/writer/test_cqasm_lite_writer.py | 2 +- test/writer/test_writer.py | 30 +++++++++++++++++---------- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/opensquirrel/ir.py b/opensquirrel/ir.py index 0d7e03e8..da686742 100644 --- a/opensquirrel/ir.py +++ b/opensquirrel/ir.py @@ -248,7 +248,7 @@ def get_qubit_operands(self) -> list[Qubit]: class Gate(Statement, ABC): - _sig_digits_repr = 5 + _significant_digits_repr = 5 def __init__( self, @@ -314,9 +314,10 @@ def identity(q: Qubit) -> BlochSphereRotation: return BlochSphereRotation(qubit=q, axis=(1, 0, 0), angle=0, phase=0) def __repr__(self) -> str: - sdr = self._sig_digits_repr - return (f"BlochSphereRotation({self.qubit}, axis={self.axis}, angle={round(self.angle, sdr)}," - f" phase={round(self.phase, sdr)})") + axis = np.round(self.axis, self._significant_digits_repr) + angle = np.round(self.angle, self._significant_digits_repr) + phase = np.round(self.phase, self._significant_digits_repr) + return f"BlochSphereRotation({self.qubit}, axis={axis}, angle={angle}, phase={phase})" def __eq__(self, other: object) -> bool: if not isinstance(other, BlochSphereRotation): @@ -362,7 +363,7 @@ def __init__( self.operands = operands def __repr__(self) -> str: - return f"MatrixGate(qubits={self.operands}, matrix={self.matrix})" + return f"MatrixGate(qubits={self.operands}, matrix={np.round(self.matrix, self._significant_digits_repr)})" def accept(self, visitor: IRVisitor) -> Any: visitor.visit_gate(self) diff --git a/test/writer/test_cqasm_lite_writer.py b/test/writer/test_cqasm_lite_writer.py index b87aab09..a8f2ea10 100644 --- a/test/writer/test_cqasm_lite_writer.py +++ b/test/writer/test_cqasm_lite_writer.py @@ -51,7 +51,7 @@ def test_anonymous_gate() -> None: qubit[2] q CR(1.234) q[0], q[1] - +BlochSphereRotation(Qubit[0], axis=[0.57735 0.57735 0.57735], angle=1.23, phase=0.0) CR(1.234) q[0], q[1] """ ) diff --git a/test/writer/test_writer.py b/test/writer/test_writer.py index 70c7f342..8eb9ab08 100644 --- a/test/writer/test_writer.py +++ b/test/writer/test_writer.py @@ -1,6 +1,9 @@ +import numpy as np + +from opensquirrel import CircuitBuilder from opensquirrel.circuit import Circuit from opensquirrel.default_gates import CR, H -from opensquirrel.ir import IR, BlochSphereRotation, Comment, Float, Qubit +from opensquirrel.ir import IR, BlochSphereRotation, Comment, ControlledGate, Float, MatrixGate, Qubit from opensquirrel.register_manager import QubitRegister, RegisterManager from opensquirrel.writer import writer @@ -36,21 +39,26 @@ def test_write() -> None: def test_anonymous_gate() -> None: - register_manager = RegisterManager(QubitRegister(2)) - ir = IR() - ir.add_gate(CR(Qubit(0), Qubit(1), Float(1.234))) - ir.add_gate(BlochSphereRotation(Qubit(0), axis=(1, 1, 1), angle=1.23)) - ir.add_gate(CR(Qubit(0), Qubit(1), Float(1.234))) - circuit = Circuit(register_manager, ir) - + qc = CircuitBuilder(2, 2) + qc.H(Qubit(0)) + qc.ir.add_gate(BlochSphereRotation(Qubit(0), axis=(1, 1, 1), angle=1.23)) + qc.ir.add_gate(ControlledGate(Qubit(0), BlochSphereRotation(Qubit(0), axis=(1, 1, 1), angle=1.23))) + qc.ir.add_gate(MatrixGate(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]), [Qubit(0), Qubit(1)])) + qc.CR(Qubit(0), Qubit(1), Float(1.234)) assert ( - writer.circuit_to_string(circuit) + writer.circuit_to_string(qc.to_circuit()) == """version 3.0 qubit[2] q +bit[2] b -CR(1.234) q[0], q[1] -BlochSphereRotation(Qubit[0], axis=Axis[0.57735027 0.57735027 0.57735027], angle=1.23, phase=0.0) +H q[0] +BlochSphereRotation(Qubit[0], axis=[0.57735 0.57735 0.57735], angle=1.23, phase=0.0) +ControlledGate(control_qubit=Qubit[0], BlochSphereRotation(Qubit[0], axis=[0.57735 0.57735 0.57735], angle=1.23, phase=0.0)) +MatrixGate(qubits=[Qubit[0], Qubit[1]], matrix=[[1 0 0 0] + [0 1 0 0] + [0 0 0 1] + [0 0 1 0]]) CR(1.234) q[0], q[1] """ ) From 8684e926192e84c52bfe828bdd8976bc9b4dc4c1 Mon Sep 17 00:00:00 2001 From: Elenbaas Date: Mon, 8 Jul 2024 15:21:18 +0200 Subject: [PATCH 03/13] Udjust Tutorial in docs to reflect new output in case of an anonymous gate. --- docs/tutorial.md | 26 +++++++++++--------------- test/docs/__init__.py | 0 test/docs/test_tutorial.py | 25 +++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 15 deletions(-) create mode 100644 test/docs/__init__.py create mode 100644 test/docs/test_tutorial.py diff --git a/docs/tutorial.md b/docs/tutorial.md index 7cb13be0..8fa5e79a 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -152,20 +152,24 @@ except Exception as e: ## Modifying a circuit -### Merging gates +### Merging single qubit gates -OpenSquirrel can merge consecutive quantum gates. Currently, this is only done for single-qubit gates. The resulting gate is labeled as an "anonymous gate". Since those gates have no name, the placeholder `` is used instead. +All single-qubit gates appearing in a circuit can be merged by applying `merge_single_qubit_gates()` to the circuit. +Note that multi-qubit gates remain untouched and single-qubit gates are not merged across any multi-qubit gates. +The gate that results from the merger of single-qubit gates will, in general, comprise an arbitrary rotation and, therefore, not be a known gate. +In OpenSquirrel an unrecognized gate is deemed _anonymous_. +When a circuit that contains anonymous gates is written to a cQASM string, the semantic representation of the anonymous gate is exported. +Note that the semantic representation of an anonymous gate is not compliant cQASM. ```python import math -builder = CircuitBuilder(qubit_register_size=1) -for i in range(16): - builder.rx(Qubit(0), Float(math.pi / 16)) +builder = CircuitBuilder(1) +for i in range(4): + builder.Rx(Qubit(0), Float(math.pi / 4)) circuit = builder.to_circuit() -# Merge single qubit gates circuit.merge_single_qubit_gates() circuit ``` @@ -174,15 +178,7 @@ circuit qubit[1] q - - -You can inspect what the gate has become in terms of the Bloch sphere rotation it represents: - -```python -circuit.ir.statements[0] -``` - - BlochSphereRotation(Qubit[0], axis=[1. 0. 0.], angle=3.141592653589795, phase=0.0) + BlochSphereRotation(Qubit[0], axis=[1. 0. 0.], angle=3.14159, phase=0.0) In the above example, OpenSquirrel has merged all the Rx gates together. Yet, for now, OpenSquirrel does not recognize that this results in a single Rx over the cumulated angle of the individual rotations. Moreover, it does not recognize that the result corresponds to the X-gate (up to a global phase difference). At a later stage, we may want OpenSquirrel to recognize the resultant gate in the case it is part of the set of known gates. diff --git a/test/docs/__init__.py b/test/docs/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test/docs/test_tutorial.py b/test/docs/test_tutorial.py new file mode 100644 index 00000000..27d85cf8 --- /dev/null +++ b/test/docs/test_tutorial.py @@ -0,0 +1,25 @@ +import math + +from opensquirrel import CircuitBuilder +from opensquirrel.ir import Float, Qubit + + +def test_anonymous_gate(): + + builder = CircuitBuilder(1) + for i in range(4): + builder.Rx(Qubit(0), Float(math.pi / 4)) + + circuit = builder.to_circuit() + + circuit.merge_single_qubit_gates() + + assert ( + str(circuit) + == """version 3.0 + +qubit[1] q + +BlochSphereRotation(Qubit[0], axis=[1. 0. 0.], angle=3.14159, phase=0.0) +""" + ) From 1aa926d7c24f122d35b68bb34f201a493c115e8b Mon Sep 17 00:00:00 2001 From: Elenbaas Date: Tue, 9 Jul 2024 12:03:49 +0200 Subject: [PATCH 04/13] Resolve review comments. --- opensquirrel/writer/writer.py | 1 + test/writer/test_writer.py | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/opensquirrel/writer/writer.py b/opensquirrel/writer/writer.py index 5e7106d8..e6ce27bd 100644 --- a/opensquirrel/writer/writer.py +++ b/opensquirrel/writer/writer.py @@ -42,6 +42,7 @@ def visit_measure(self, measure: Measure) -> None: def visit_gate(self, gate: Gate) -> None: gate_name = gate.name if gate.is_anonymous: + gate_name = gate_name.replace("\n", "") self.output += f"{gate_name}\n" return if any(not isinstance(arg, Qubit) for arg in gate.arguments): # type: ignore[union-attr] diff --git a/test/writer/test_writer.py b/test/writer/test_writer.py index 8eb9ab08..dbdadd05 100644 --- a/test/writer/test_writer.py +++ b/test/writer/test_writer.py @@ -55,10 +55,7 @@ def test_anonymous_gate() -> None: H q[0] BlochSphereRotation(Qubit[0], axis=[0.57735 0.57735 0.57735], angle=1.23, phase=0.0) ControlledGate(control_qubit=Qubit[0], BlochSphereRotation(Qubit[0], axis=[0.57735 0.57735 0.57735], angle=1.23, phase=0.0)) -MatrixGate(qubits=[Qubit[0], Qubit[1]], matrix=[[1 0 0 0] - [0 1 0 0] - [0 0 0 1] - [0 0 1 0]]) +MatrixGate(qubits=[Qubit[0], Qubit[1]], matrix=[[1 0 0 0] [0 1 0 0] [0 0 0 1] [0 0 1 0]]) CR(1.234) q[0], q[1] """ ) From d4dc2c7d4bcc3c8dfc995d8844d09f00e9dc7bcb Mon Sep 17 00:00:00 2001 From: Chris Elenbaas <67630508+elenbaasc@users.noreply.github.com> Date: Fri, 12 Jul 2024 13:33:14 +0200 Subject: [PATCH 05/13] Update test/writer/test_writer.py Co-authored-by: Roberto Turrado Camblor --- test/writer/test_writer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/writer/test_writer.py b/test/writer/test_writer.py index dbdadd05..ba1153a7 100644 --- a/test/writer/test_writer.py +++ b/test/writer/test_writer.py @@ -46,7 +46,7 @@ def test_anonymous_gate() -> None: qc.ir.add_gate(MatrixGate(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]), [Qubit(0), Qubit(1)])) qc.CR(Qubit(0), Qubit(1), Float(1.234)) assert ( - writer.circuit_to_string(qc.to_circuit()) + str(qc.to_circuit()) == """version 3.0 qubit[2] q From e729465c52a53525eda60683c534938837845654 Mon Sep 17 00:00:00 2001 From: Chris Elenbaas <67630508+elenbaasc@users.noreply.github.com> Date: Fri, 12 Jul 2024 13:34:13 +0200 Subject: [PATCH 06/13] Update test/docs/test_tutorial.py Co-authored-by: Roberto Turrado Camblor --- test/docs/test_tutorial.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/docs/test_tutorial.py b/test/docs/test_tutorial.py index 27d85cf8..0f43b6c6 100644 --- a/test/docs/test_tutorial.py +++ b/test/docs/test_tutorial.py @@ -5,15 +5,11 @@ def test_anonymous_gate(): - builder = CircuitBuilder(1) for i in range(4): builder.Rx(Qubit(0), Float(math.pi / 4)) - circuit = builder.to_circuit() - circuit.merge_single_qubit_gates() - assert ( str(circuit) == """version 3.0 From 4ed25c03cd8ef2d4b82f2f7a5a43572e4a33b610 Mon Sep 17 00:00:00 2001 From: Chris Elenbaas <67630508+elenbaasc@users.noreply.github.com> Date: Fri, 12 Jul 2024 13:34:25 +0200 Subject: [PATCH 07/13] Update opensquirrel/ir.py Co-authored-by: Roberto Turrado Camblor --- opensquirrel/ir.py | 1 - 1 file changed, 1 deletion(-) diff --git a/opensquirrel/ir.py b/opensquirrel/ir.py index da686742..cf483340 100644 --- a/opensquirrel/ir.py +++ b/opensquirrel/ir.py @@ -247,7 +247,6 @@ def get_qubit_operands(self) -> list[Qubit]: class Gate(Statement, ABC): - _significant_digits_repr = 5 def __init__( From 087445b00bcc13976e4383293e42e4adbe69d692 Mon Sep 17 00:00:00 2001 From: Elenbaas Date: Fri, 12 Jul 2024 14:37:19 +0200 Subject: [PATCH 08/13] Resolve review comments. --- docs/tutorial.md | 2 +- opensquirrel/ir.py | 13 +++++++------ opensquirrel/writer/writer.py | 5 ++++- test/docs/test_tutorial.py | 2 +- test/writer/test_cqasm_lite_writer.py | 2 +- test/writer/test_writer.py | 6 +++--- 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/docs/tutorial.md b/docs/tutorial.md index 8fa5e79a..29633632 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -178,7 +178,7 @@ circuit qubit[1] q - BlochSphereRotation(Qubit[0], axis=[1. 0. 0.], angle=3.14159, phase=0.0) + Anonymous gate: BlochSphereRotation(Qubit[0], axis=[1. 0. 0.], angle=3.14159, phase=0.0) In the above example, OpenSquirrel has merged all the Rx gates together. Yet, for now, OpenSquirrel does not recognize that this results in a single Rx over the cumulated angle of the individual rotations. Moreover, it does not recognize that the result corresponds to the X-gate (up to a global phase difference). At a later stage, we may want OpenSquirrel to recognize the resultant gate in the case it is part of the set of known gates. diff --git a/opensquirrel/ir.py b/opensquirrel/ir.py index da686742..5cef7f0d 100644 --- a/opensquirrel/ir.py +++ b/opensquirrel/ir.py @@ -270,7 +270,7 @@ def __eq__(self, other: object) -> bool: def name(self) -> str: if self.generator: return self.generator.__name__ - return self.__repr__() + return "Anonymous gate: " + self.__repr__() @property def is_anonymous(self) -> bool: @@ -292,6 +292,9 @@ def is_identity(self) -> bool: Boolean value stating whether the Gate is an identity Gate. """ + def _round(self, value: float | AxisLike) -> float | AxisLike: + return np.round(value, self._significant_digits_repr) + class BlochSphereRotation(Gate): def __init__( @@ -314,10 +317,8 @@ def identity(q: Qubit) -> BlochSphereRotation: return BlochSphereRotation(qubit=q, axis=(1, 0, 0), angle=0, phase=0) def __repr__(self) -> str: - axis = np.round(self.axis, self._significant_digits_repr) - angle = np.round(self.angle, self._significant_digits_repr) - phase = np.round(self.phase, self._significant_digits_repr) - return f"BlochSphereRotation({self.qubit}, axis={axis}, angle={angle}, phase={phase})" + return (f"BlochSphereRotation({self.qubit}, axis={self._round(self.axis)}, angle={self._round(self.angle)}," + f" phase={self._round(self.phase)})") def __eq__(self, other: object) -> bool: if not isinstance(other, BlochSphereRotation): @@ -363,7 +364,7 @@ def __init__( self.operands = operands def __repr__(self) -> str: - return f"MatrixGate(qubits={self.operands}, matrix={np.round(self.matrix, self._significant_digits_repr)})" + return f"MatrixGate(qubits={self.operands}, matrix={self._round(self.matrix)})" def accept(self, visitor: IRVisitor) -> Any: visitor.visit_gate(self) diff --git a/opensquirrel/writer/writer.py b/opensquirrel/writer/writer.py index e6ce27bd..e6ebab53 100644 --- a/opensquirrel/writer/writer.py +++ b/opensquirrel/writer/writer.py @@ -42,7 +42,10 @@ def visit_measure(self, measure: Measure) -> None: def visit_gate(self, gate: Gate) -> None: gate_name = gate.name if gate.is_anonymous: - gate_name = gate_name.replace("\n", "") + if "MatrixGate" in gate_name: + # In the case of a MatrixGate the newline escapes (\n) should be removed from the array such that the + # array is printed on a single line. + gate_name = gate_name.replace("\n", "") self.output += f"{gate_name}\n" return if any(not isinstance(arg, Qubit) for arg in gate.arguments): # type: ignore[union-attr] diff --git a/test/docs/test_tutorial.py b/test/docs/test_tutorial.py index 27d85cf8..5e9d18fc 100644 --- a/test/docs/test_tutorial.py +++ b/test/docs/test_tutorial.py @@ -20,6 +20,6 @@ def test_anonymous_gate(): qubit[1] q -BlochSphereRotation(Qubit[0], axis=[1. 0. 0.], angle=3.14159, phase=0.0) +Anonymous gate: BlochSphereRotation(Qubit[0], axis=[1. 0. 0.], angle=3.14159, phase=0.0) """ ) diff --git a/test/writer/test_cqasm_lite_writer.py b/test/writer/test_cqasm_lite_writer.py index a8f2ea10..bcd6e821 100644 --- a/test/writer/test_cqasm_lite_writer.py +++ b/test/writer/test_cqasm_lite_writer.py @@ -51,7 +51,7 @@ def test_anonymous_gate() -> None: qubit[2] q CR(1.234) q[0], q[1] -BlochSphereRotation(Qubit[0], axis=[0.57735 0.57735 0.57735], angle=1.23, phase=0.0) +Anonymous gate: BlochSphereRotation(Qubit[0], axis=[0.57735 0.57735 0.57735], angle=1.23, phase=0.0) CR(1.234) q[0], q[1] """ ) diff --git a/test/writer/test_writer.py b/test/writer/test_writer.py index dbdadd05..7a44e020 100644 --- a/test/writer/test_writer.py +++ b/test/writer/test_writer.py @@ -53,9 +53,9 @@ def test_anonymous_gate() -> None: bit[2] b H q[0] -BlochSphereRotation(Qubit[0], axis=[0.57735 0.57735 0.57735], angle=1.23, phase=0.0) -ControlledGate(control_qubit=Qubit[0], BlochSphereRotation(Qubit[0], axis=[0.57735 0.57735 0.57735], angle=1.23, phase=0.0)) -MatrixGate(qubits=[Qubit[0], Qubit[1]], matrix=[[1 0 0 0] [0 1 0 0] [0 0 0 1] [0 0 1 0]]) +Anonymous gate: BlochSphereRotation(Qubit[0], axis=[0.57735 0.57735 0.57735], angle=1.23, phase=0.0) +Anonymous gate: ControlledGate(control_qubit=Qubit[0], BlochSphereRotation(Qubit[0], axis=[0.57735 0.57735 0.57735], angle=1.23, phase=0.0)) +Anonymous gate: MatrixGate(qubits=[Qubit[0], Qubit[1]], matrix=[[1 0 0 0] [0 1 0 0] [0 0 0 1] [0 0 1 0]]) CR(1.234) q[0], q[1] """ ) From 1a351bab5fbdf4bda7b7bfa9a9306be225d7cdc4 Mon Sep 17 00:00:00 2001 From: Elenbaas Date: Fri, 12 Jul 2024 14:42:58 +0200 Subject: [PATCH 09/13] Run black. --- opensquirrel/ir.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/opensquirrel/ir.py b/opensquirrel/ir.py index 8ab980e1..2697fdd8 100644 --- a/opensquirrel/ir.py +++ b/opensquirrel/ir.py @@ -316,8 +316,10 @@ def identity(q: Qubit) -> BlochSphereRotation: return BlochSphereRotation(qubit=q, axis=(1, 0, 0), angle=0, phase=0) def __repr__(self) -> str: - return (f"BlochSphereRotation({self.qubit}, axis={self._round(self.axis)}, angle={self._round(self.angle)}," - f" phase={self._round(self.phase)})") + return ( + f"BlochSphereRotation({self.qubit}, axis={self._round(self.axis)}, angle={self._round(self.angle)}," + f" phase={self._round(self.phase)})" + ) def __eq__(self, other: object) -> bool: if not isinstance(other, BlochSphereRotation): From 26a70b82727dea89d4beb933ce703004bfe02880 Mon Sep 17 00:00:00 2001 From: Elenbaas Date: Fri, 12 Jul 2024 16:39:22 +0200 Subject: [PATCH 10/13] Sort out typing error. --- opensquirrel/ir.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opensquirrel/ir.py b/opensquirrel/ir.py index 2697fdd8..84d0ec0e 100644 --- a/opensquirrel/ir.py +++ b/opensquirrel/ir.py @@ -291,7 +291,7 @@ def is_identity(self) -> bool: Boolean value stating whether the Gate is an identity Gate. """ - def _round(self, value: float | AxisLike) -> float | AxisLike: + def _round(self, value: float | Axis | NDArray[np.complex64]) -> float | Axis | NDArray[np.complex64]: return np.round(value, self._significant_digits_repr) From 1bc392b4df8725498e543580fcb7d1ec71ff3dda Mon Sep 17 00:00:00 2001 From: Chris Elenbaas <67630508+elenbaasc@users.noreply.github.com> Date: Tue, 16 Jul 2024 13:20:04 +0200 Subject: [PATCH 11/13] Update opensquirrel/writer/writer.py Co-authored-by: Roberto Turrado Camblor --- opensquirrel/writer/writer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opensquirrel/writer/writer.py b/opensquirrel/writer/writer.py index e6ebab53..8eefb682 100644 --- a/opensquirrel/writer/writer.py +++ b/opensquirrel/writer/writer.py @@ -43,8 +43,8 @@ def visit_gate(self, gate: Gate) -> None: gate_name = gate.name if gate.is_anonymous: if "MatrixGate" in gate_name: - # In the case of a MatrixGate the newline escapes (\n) should be removed from the array such that the - # array is printed on a single line. + # In the case of a MatrixGate the newlines should be removed from the array + # such that the array is printed on a single line. gate_name = gate_name.replace("\n", "") self.output += f"{gate_name}\n" return From 130df4aeb0ee1120b921c8ddb20b1018b457fede Mon Sep 17 00:00:00 2001 From: Elenbaas Date: Tue, 16 Jul 2024 13:45:46 +0200 Subject: [PATCH 12/13] Resolve comments. --- opensquirrel/ir.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/opensquirrel/ir.py b/opensquirrel/ir.py index 84d0ec0e..54954350 100644 --- a/opensquirrel/ir.py +++ b/opensquirrel/ir.py @@ -13,6 +13,15 @@ from opensquirrel.common import ATOL, are_matrices_equivalent_up_to_global_phase, normalize_angle +_REPR_DECIMALS = 5 + + +def _repr_round( + value: float | Axis | NDArray[np.complex64], + decimals: int = _REPR_DECIMALS) -> float | Axis | NDArray[np.complex64]: + return np.round(value, decimals) + + class IRVisitor(ABC): def visit_comment(self, comment: Comment) -> Any: pass @@ -247,7 +256,6 @@ def get_qubit_operands(self) -> list[Qubit]: class Gate(Statement, ABC): - _significant_digits_repr = 5 def __init__( self, @@ -291,9 +299,6 @@ def is_identity(self) -> bool: Boolean value stating whether the Gate is an identity Gate. """ - def _round(self, value: float | Axis | NDArray[np.complex64]) -> float | Axis | NDArray[np.complex64]: - return np.round(value, self._significant_digits_repr) - class BlochSphereRotation(Gate): def __init__( @@ -317,8 +322,8 @@ def identity(q: Qubit) -> BlochSphereRotation: def __repr__(self) -> str: return ( - f"BlochSphereRotation({self.qubit}, axis={self._round(self.axis)}, angle={self._round(self.angle)}," - f" phase={self._round(self.phase)})" + f"BlochSphereRotation({self.qubit}, axis={_repr_round(self.axis)}, angle={_repr_round(self.angle)}," + f" phase={_repr_round(self.phase)})" ) def __eq__(self, other: object) -> bool: @@ -365,7 +370,7 @@ def __init__( self.operands = operands def __repr__(self) -> str: - return f"MatrixGate(qubits={self.operands}, matrix={self._round(self.matrix)})" + return f"MatrixGate(qubits={self.operands}, matrix={_repr_round(self.matrix)})" def accept(self, visitor: IRVisitor) -> Any: visitor.visit_gate(self) From 7e0acb251b4e6392d326de3f4d6408fe0c885e12 Mon Sep 17 00:00:00 2001 From: Elenbaas Date: Tue, 16 Jul 2024 14:48:47 +0200 Subject: [PATCH 13/13] Remove underscores from global function and variable. --- opensquirrel/ir.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/opensquirrel/ir.py b/opensquirrel/ir.py index 54954350..be664d13 100644 --- a/opensquirrel/ir.py +++ b/opensquirrel/ir.py @@ -12,13 +12,12 @@ from opensquirrel.common import ATOL, are_matrices_equivalent_up_to_global_phase, normalize_angle +REPR_DECIMALS = 5 -_REPR_DECIMALS = 5 - -def _repr_round( - value: float | Axis | NDArray[np.complex64], - decimals: int = _REPR_DECIMALS) -> float | Axis | NDArray[np.complex64]: +def repr_round( + value: float | Axis | NDArray[np.complex64], decimals: int = REPR_DECIMALS +) -> float | Axis | NDArray[np.complex64]: return np.round(value, decimals) @@ -322,8 +321,8 @@ def identity(q: Qubit) -> BlochSphereRotation: def __repr__(self) -> str: return ( - f"BlochSphereRotation({self.qubit}, axis={_repr_round(self.axis)}, angle={_repr_round(self.angle)}," - f" phase={_repr_round(self.phase)})" + f"BlochSphereRotation({self.qubit}, axis={repr_round(self.axis)}, angle={repr_round(self.angle)}," + f" phase={repr_round(self.phase)})" ) def __eq__(self, other: object) -> bool: @@ -370,7 +369,7 @@ def __init__( self.operands = operands def __repr__(self) -> str: - return f"MatrixGate(qubits={self.operands}, matrix={_repr_round(self.matrix)})" + return f"MatrixGate(qubits={self.operands}, matrix={repr_round(self.matrix)})" def accept(self, visitor: IRVisitor) -> Any: visitor.visit_gate(self)