Skip to content

Commit 0d321ff

Browse files
elenbaascGuyPutsjuanboscherorturradodependabot[bot]
authored
Release 0.2.0 (#431)
Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Guy Puts <guy.puts@tno.nl> Co-authored-by: Guy Puts <38719377+GuyPuts@users.noreply.github.com> Co-authored-by: Juan Boschero <juan.boschero@tno.nl> Co-authored-by: rturrado <rturrado@gmail.com> Co-authored-by: Juan Carlos Boschero <juanboschero1998@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: rares1609 <79575613+rares1609@users.noreply.github.com> Co-authored-by: Oancea <rares.oancea@tno.nl>
1 parent 2e586b3 commit 0d321ff

File tree

100 files changed

+6242
-4120
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+6242
-4120
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
This project adheres to [Semantic Versioning](http://semver.org/).
5+
6+
### Types of changes:
7+
* **Added** for new features.
8+
* **Changed** for changes in existing functionality.
9+
* **Fixed** for any bug fixes.
10+
* **Removed** for now removed features.
11+
12+
13+
## [ 0.2.0 ] - [ xxxx-yy-zz ]
14+
15+
### Added
16+
- Restore SGMQ notation for barrier groups in cQASMv1 Exporter.

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ Make sure the tests and the following linters pass.
3333
From a `poetry` shell (started from an OpenSquirrel checkout):
3434

3535
```
36+
$ poetry run mypy opensquirrel test --strict
3637
$ poetry run pytest . -vv
3738
$ poetry run ruff check --fix
3839
$ poetry run ruff format
39-
$ poetry run mypy opensquirrel --strict
4040
```
4141

4242
## Setting the Python interpreter (PyCharm)

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ Here is an example of building a circuit using the `CircuitBuilder`:
6363
```python
6464
import math
6565
from opensquirrel.circuit_builder import CircuitBuilder
66-
from opensquirrel.ir import Qubit, Float
66+
from opensquirrel.ir import Qubit
6767

6868
# Initialize the builder and build your circuit
6969
builder = CircuitBuilder(qubit_register_size=1)
70-
builder.H(Qubit(0)).Z(Qubit(0)).Y(Qubit(0)).Rx(Qubit(0), Float(math.pi / 3))
70+
builder.H(Qubit(0)).Z(Qubit(0)).Y(Qubit(0)).Rx(Qubit(0), math.pi / 3)
7171

7272
# Get the circuit from the circuit builder
7373
qc = builder.to_circuit()
@@ -97,7 +97,7 @@ The different decomposition strategies can be found in the
9797
In the example below, the circuit is decomposed using the Z-Y-Z decomposer.
9898

9999
```python
100-
from opensquirrel.decomposer.aba_decomposer import ZYZDecomposer
100+
from opensquirrel.passes.decomposer.aba_decomposer import ZYZDecomposer
101101

102102
qc.decompose(decomposer=ZYZDecomposer())
103103
```

docs/_static/cnot2cz.png

113 KB
Loading

docs/_static/swap2cnot.png

129 KB
Loading

docs/tutorial.md

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,10 @@ _Output_:
6464
For creation of a circuit through Python, the `CircuitBuilder` can be used accordingly:
6565

6666
```python
67-
from opensquirrel import CircuitBuilder
68-
from opensquirrel.ir import Float
67+
from opensquirrel.circuit_builder import CircuitBuilder
6968

7069
builder = CircuitBuilder(qubit_register_size=2)
71-
builder.Ry(0, Float(0.23)).CNOT(0, 1)
70+
builder.Ry(0, 0.23).CNOT(0, 1)
7271
qc = builder.to_circuit()
7372

7473
print(qc)
@@ -85,6 +84,8 @@ _Output_:
8584
You can naturally use the functionalities available in Python to create your circuit:
8685

8786
```python
87+
from opensquirrel.circuit_builder import CircuitBuilder
88+
8889
builder = CircuitBuilder(qubit_register_size=10)
8990
for i in range(0, 10, 2):
9091
builder.H(i)
@@ -107,6 +108,8 @@ _Output_:
107108
For instance, you can generate a quantum fourier transform (QFT) circuit as follows:
108109

109110
```python
111+
from opensquirrel.circuit_builder import CircuitBuilder
112+
110113
qubit_register_size = 5
111114
builder = CircuitBuilder(qubit_register_size)
112115
for i in range(qubit_register_size):
@@ -144,6 +147,8 @@ _Output_:
144147
As you can see, gates require _strong types_. For instance, you cannot do:
145148

146149
```python
150+
from opensquirrel.circuit import Circuit
151+
147152
try:
148153
Circuit.from_string(
149154
"""
@@ -160,13 +165,13 @@ _Output_:
160165

161166
Parsing error: failed to resolve overload for cnot with argument pack (qubit, int)
162167

163-
The issue is that the CNOT expects a qubit as second input argument where an integer has been provided.
168+
The issue is that the `CNOT` expects a qubit as second input argument where an integer has been provided.
164169

165170
## Modifying a circuit
166171

167172
### Merging single qubit gates
168173

169-
All single-qubit gates appearing in a circuit can be merged by applying `merge_single_qubit_gates()` to the circuit.
174+
All single-qubit gates appearing in a circuit can be merged by applying `merge(merger=SingleQubitGatesMerger())` to the circuit.
170175
Note that multi-qubit gates remain untouched and single-qubit gates are not merged across any multi-qubit gates.
171176
The gate that results from the merger of single-qubit gates will, in general,
172177
comprise an arbitrary rotation and, therefore, not be a known gate.
@@ -182,14 +187,17 @@ the semantic representation of the anonymous gate is exported.
182187
will not recognize it as a valid statement.
183188

184189
```python
190+
from opensquirrel.circuit_builder import CircuitBuilder
191+
from opensquirrel.passes.merger import SingleQubitGatesMerger
192+
from opensquirrel.ir import Float
185193
import math
186194

187195
builder = CircuitBuilder(1)
188196
for _ in range(4):
189-
builder.Rx(0, Float(math.pi / 4))
197+
builder.Rx(0, math.pi / 4)
190198
qc = builder.to_circuit()
191199

192-
qc.merge_single_qubit_gates()
200+
qc.merge(merger=SingleQubitGatesMerger())
193201

194202
print(qc)
195203
```
@@ -222,6 +230,9 @@ It accepts a qubit, an axis, an angle, and a phase as arguments.
222230
Below is shown how the X-gate is defined in the default gate set of OpenSquirrel:
223231

224232
```python
233+
from opensquirrel.ir import Gate, BlochSphereRotation, QubitLike, named_gate
234+
import math
235+
225236
@named_gate
226237
def x(q: QubitLike) -> Gate:
227238
return BlochSphereRotation(qubit=q, axis=(1, 0, 0), angle=math.pi, phase=math.pi / 2)
@@ -232,17 +243,22 @@ This _tells_ OpenSquirrel that the function defines a gate and that it should,
232243
therefore, have all the nice properties OpenSquirrel expects of it.
233244

234245
- The `ControlledGate` class is used to define a multiple qubit gate that comprises a controlled operation.
235-
For instance, the CNOT gate is defined in the default gate set of OpenSquirrel as follows:
246+
For instance, the `CNOT` gate is defined in the default gate set of OpenSquirrel as follows:
236247

237248
```python
249+
from opensquirrel.ir import Gate, ControlledGate, QubitLike, named_gate
250+
from opensquirrel import X
251+
238252
@named_gate
239253
def cnot(control: QubitLike, target: QubitLike) -> Gate:
240-
return ControlledGate(control, x(target))
254+
return ControlledGate(control, X(target))
241255
```
242256

243257
- The `MatrixGate` class may be used to define a gate in the generic form of a matrix:
244258

245259
```python
260+
from opensquirrel.ir import Gate, MatrixGate, QubitLike, named_gate
261+
246262
@named_gate
247263
def swap(q1: QubitLike, q2: QubitLike) -> Gate:
248264
return MatrixGate(
@@ -274,13 +290,14 @@ Decompositions can be:
274290
#### 1. Predefined decomposition
275291

276292
The first kind of decomposition is when you want to replace a particular gate in the circuit,
277-
like the CNOT gate, with a fixed list of gates.
278-
It is commonly known that CNOT can be decomposed as H-CZ-H.
293+
like the `CNOT` gate, with a fixed list of gates.
294+
It is commonly known that `CNOT` can be decomposed as `H`-`CZ`-`H`.
279295
This decomposition is demonstrated below using a Python _lambda function_,
280296
which requires the same parameters as the gate that is decomposed:
281297

282298
```python
283-
from opensquirrel.default_gates import CNOT, H, CZ
299+
from opensquirrel.circuit import Circuit
300+
from opensquirrel import CNOT, H, CZ
284301

285302
qc = Circuit.from_string(
286303
"""
@@ -323,6 +340,9 @@ For instance, an exception is thrown if we forget the final Hadamard,
323340
or H gate, in our custom-made decomposition:
324341

325342
```python
343+
from opensquirrel.circuit import Circuit
344+
from opensquirrel import CNOT, CZ, H
345+
326346
qc = Circuit.from_string(
327347
"""
328348
version 3.0
@@ -349,21 +369,42 @@ _Output_:
349369

350370
replacement for gate CNOT does not preserve the quantum state
351371

372+
##### _`CNOT` to `CZ` decomposer_
373+
374+
The decomposition of the `CNOT` gate into a `CZ` gate (with additional single-qubit gates) is used frequently.
375+
To this end a `CNOT2CZDecomposer` has been implemented that decomposes any `CNOT`s in a circuit to a
376+
`Ry(-π/2)`-`CZ`-`Ry(π/2)`. The decomposition is illustrated in the image below.
377+
378+
<p align="center"> <img width="600" src="_static/cnot2cz.png"> </p>
379+
380+
`Ry` gates are used instead of, _e.g._, `H` gates, as they are, generally,
381+
more likely to be supported already by target backends.
382+
383+
##### _`SWAP` to `CNOT` decomposer_
384+
385+
The `SWAP2CNOTDecomposer` implements the predefined decomposition of the `SWAP` gate into 3 `CNOT` gates.
386+
The decomposition is illustrated in the image below.
387+
388+
<p align="center"> <img width="600" src="_static/swap2cnot.png"> </p>
389+
390+
352391
#### 2. Inferred decomposition
353392

354393
OpenSquirrel has a variety inferred decomposition strategies.
355394
More in depth tutorials can be found in the [decomposition example Jupyter notebook](https://github.com/QuTech-Delft/OpenSquirrel/blob/develop/example/decompositions.ipynb).
356395

357-
One of the most common single qubit decomposition techniques is the Z-Y-Z decomposition.
396+
One of the most common single qubit decomposition techniques is the ZYZ decomposition.
358397
This technique decomposes a quantum gate into an `Rz`, `Ry` and `Rz` gate in that order.
359-
The decompositions are found in `opensquirrel.decomposer`,
360-
an example can be seen below where a Hadamard, Z, Y and Rx gate are all decomposed on a single qubit circuit.
398+
The decompositions are found in `opensquirrel.passes.decomposer`,
399+
an example can be seen below where a `H`, `Z`, `Y`, and `Rx` gate are all decomposed on a single qubit circuit.
361400

362401
```python
363-
from opensquirrel.decomposer.aba_decomposer import ZYZDecomposer
402+
from opensquirrel.circuit_builder import CircuitBuilder
403+
from opensquirrel.passes.decomposer import ZYZDecomposer
404+
import math
364405

365406
builder = CircuitBuilder(qubit_register_size=1)
366-
builder.H(0).Z(0).Y(0).Rx(0, Float(math.pi / 3))
407+
builder.H(0).Z(0).Y(0).Rx(0, math.pi / 3)
367408
qc = builder.to_circuit()
368409

369410
qc.decompose(decomposer=ZYZDecomposer())
@@ -387,8 +428,8 @@ _Output_:
387428
Similarly, the decomposer can be used on individual gates.
388429

389430
```python
390-
from opensquirrel.decomposer.aba_decomposer import XZXDecomposer
391-
from opensquirrel.default_gates import H
431+
from opensquirrel.passes.decomposer import ZYZDecomposer
432+
from opensquirrel import H
392433

393434
print(ZYZDecomposer().decompose(H(0)))
394435
```

0 commit comments

Comments
 (0)