Skip to content

Commit

Permalink
update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
dakk committed Oct 27, 2023
1 parent 829b90e commit e8bb87b
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 23 deletions.
52 changes: 37 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,41 @@
![License: Apache 2.0](https://img.shields.io/badge/license-Apache_2.0-blue)


Qlasskit is a Python library that allows quantum developers to write classical algorithms in pure Python and translate them into unitary operators (gates) for use in quantum circuits.
Qlasskit is a Python library that allows quantum developers to write classical algorithms in pure Python and translate them into unitary operators (gates) for use in quantum circuits, using boolean expressions as intermediate form.

This tool will be useful for any algorithm that relies on a 'blackbox' function and for describing the classical components of a quantum algorithm.



```python
@qlassf
def f(n: Qint4) -> bool:
if n == 3:
return True
else:
return False
def hash(k: Qint4) -> bool:
h = True
for i in range(4):
h = h and k[i]
return h
```

And then use it inside a circuit:
Qlasskit will take care of translating the function to boolean expressions, simplify them and
translate to a quantum circuit.

![Groover](https://github.com/dakk/qlasskit/docs/source/_images/hash_circ.png?raw=true)

Then, we can use groover to find which hash(k) returns True:

```python
qc = QuantumCircuit(f.num_qubits)
...
qc.append(f.gate(), f.qubits_list(0))
from qlasskit.algorithms import Groover

algo = Groover(hash, True)
qc = algo.circuit().export("circuit", "qiskit")
```

Or, you can define a function with parameters:
And that's it:

![Groover](https://github.com/dakk/qlasskit/docs/source/_images/grover_circ.png?raw=true)


You can also define a function with parameters:
```python
@qlassf
def f(n: Qint4, n_it: Param[int]) -> Qint8:
Expand All @@ -40,12 +52,22 @@ def f(n: Qint4, n_it: Param[int]) -> Qint8:
And then, you can bind it with a value:
```python
f4 = f.bind(n_it=4)
qc = QuantumCircuit(f4.num_qubits)
...
qc.append(f4.gate(), f4.qubits_list(0))
```

Qlasskit (will) supports complex data types, like tuples and fixed size lists:
Use other functions:

```python
@qlassf
def equal_8(n: Qint4) -> bool:
return equal_8

@qlassf
def f(n: Qint4) -> bool:
n = n+1 if equal_8(n) else n
return n
```

Qlasskit supports complex data types, like tuples and fixed size lists:

```python
@qlassf
Expand Down
4 changes: 4 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,12 @@
- [x] Aggregate cascading expressions in for unrolling
- [x] Rewrite qcircuit abstraction
- [x] Inner function
- [x] Groover algorithm

### Week 2: (30 Oct 23)

- [ ] Groover algorithm tests

### Week 3: (6 Nov 23)

- [ ] Slideshow for UF midterm
Expand Down
Binary file added docs/source/_images/groover_circ.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/_images/hash_circ.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions examples/groover_hash_collision.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

def qiskit_simulate(qc):
qc.measure_all()
print(qc.draw("text"))
print(qc.draw('text'))

simulator = Aer.get_backend("aer_simulator")
circ = transpile(qc, simulator)
Expand Down Expand Up @@ -55,4 +55,5 @@ def hash(k: Qint4) -> Qint4:
plt.show()


# print (hash.circuit().export("circuit", 'qiskit').draw('text'))
print(hash.circuit().export("circuit", 'qiskit').draw('text'))
# plt.show()
10 changes: 5 additions & 5 deletions qlasskit/algorithms/groover.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def __init__(
self.qc = QCircuit(self.search_space_size)

# State preparation
self.qc.barrier(label="state_prep")
self.qc.barrier(label="s")
for i in range(self.search_space_size):
self.qc.h(i)

Expand Down Expand Up @@ -97,16 +97,16 @@ def oracle_outer(v: {argt_name}) -> bool:
]
self.qc.h(oracle_qc["_ret_phased"])

self.qc.barrier(label="groover")

for i in range(n_iterations):
self.qc.barrier(label=f"orac_{i}")
self.qc.barrier(label=f"g{i}")
# self.qc.barrier(label=f"orac_{i}")
self.qc += oracle_qc.copy()

self.qc.barrier(label=f"diff_{i}")
# self.qc.barrier(label=f"diff_{i}")
self.qc += diffuser_qc.copy()

self.qc.barrier(label="end")
# self.qc.barrier(label="end")

def circuit(self) -> QCircuit:
return self.qc
Expand Down
10 changes: 9 additions & 1 deletion qlasskit/algorithms/qalgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,15 @@ def out_qubits(self) -> List[int]:

def interpet_counts(self, counts: Dict[str, int]) -> Dict[Any, int]:
"""Interpet data inside a circuit counts dict"""
return dict((self.interpret_outcome(e), c) for (e, c) in counts.items())
l = [(self.interpret_outcome(e), c) for (e, c) in counts.items()]
d = {}
for (e, c) in l:
inter = self.interpret_outcome(e)
if inter in d:
d[inter] += c
else:
d[inter] = c
return d

def export(self, framework: SupportedFramework = "qiskit") -> Any:
"""Export the algorithm to a supported framework"""
Expand Down

0 comments on commit e8bb87b

Please sign in to comment.