Skip to content

Commit

Permalink
deutsch jozsa algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
dakk committed Nov 27, 2023
1 parent 1f472bd commit efbf288
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 2 deletions.
7 changes: 5 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
- [x] Hash function preimage attack notebook
- [x] Move all examples to doc
- [x] Simon periodicity
- [x] Deutsch-Jozsa
- [ ] Improve documentation
- [ ] First stable release

Expand All @@ -134,9 +135,11 @@
- [ ] Builtin function: map
- [ ] First beta release

### Algorithms
### Docs

- [ ] Simon example
- [ ] Deutsch-Jozsa example

- [ ] Deutsch-Jozsa

### Language support

Expand Down
1 change: 1 addition & 0 deletions qlasskit/algorithms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
)
from .grover import Grover # noqa: F401, E402
from .simon import Simon # noqa: F401, E402
from .deutschjozsa import DeutschJozsa # noqa: F401, E402
74 changes: 74 additions & 0 deletions qlasskit/algorithms/deutschjozsa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Copyright 2023 Davide Gessa

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import List, Tuple, Union

from ..qcircuit import QCircuit
from ..qlassfun import QlassF
from ..types import Qtype, interpret_as_qtype
from .qalgorithm import QAlgorithm


class DeutschJozsa(QAlgorithm):
def __init__(
self,
f: QlassF,
):
"""
Args:
f (QlassF): our f(x) -> bool
"""
if len(f.args) != 1:
raise Exception("f should receive exactly one parameter")
if f.returns.ttype != bool:
raise Exception("f should returns bool")

self.f: QlassF = f
self.search_space_size = len(f.args[0])
self._qcircuit = QCircuit(self.f.num_qubits)

self._f_circuit = self.f.circuit()

# State preparation
self._qcircuit.barrier(label="s")
for i in range(self.search_space_size):
self._qcircuit.h(i)
self._qcircuit.x(self._f_circuit["_ret"])
self._qcircuit.h(self._f_circuit["_ret"])

# Prepare and add the f
self._qcircuit.barrier(label="f")
self._qcircuit += self._f_circuit

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

# @override
@property
def output_qubits(self) -> List[int]:
"""Returns the list of output qubits"""
len_a = len(self.f.args[0])
return list(range(len_a))

# @override
def decode_output(
self, istr: Union[str, int, List[bool]]
) -> Union[bool, Tuple, Qtype]:
iq = interpret_as_qtype(istr, self.f.args[0].ttype, len(self.f.args[0]))
if iq == 0:
return "Constant"
else:
return "Balanced"
1 change: 1 addition & 0 deletions qlasskit/algorithms/simon.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def __init__(
self._qcircuit.h(i)

# Prepare and add the f
self._qcircuit.barrier(label="f")
self._qcircuit += self.f.circuit()

# State preparation out
Expand Down
61 changes: 61 additions & 0 deletions test/test_algo_deutschjozsa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Copyright 2023 Davide Gessa

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest

from qlasskit import Qint2, Qint4, qlassf
from qlasskit.algorithms import DeutschJozsa

from .utils import qiskit_measure_and_count


class TestAlgoDeutschJozsa(unittest.TestCase):
def test_deutschjozsa_balanced(self):
f = """
def hash(k: Qint2) -> bool:
return k[0] ^ k[1]
"""
qf = qlassf(f, compiler="tweedledum")
algo = DeutschJozsa(qf)

qc_algo = algo.circuit().export("circuit", "qiskit")
counts = qiskit_measure_and_count(qc_algo, shots=1024)
counts_readable = algo.decode_counts(counts)
self.assertEqual(counts_readable["Balanced"], 1024)

def test_deutschjozsa_balanced2(self):
f = """
def hash(k: bool) -> bool:
return k
"""
qf = qlassf(f, compiler="tweedledum")
algo = DeutschJozsa(qf)

qc_algo = algo.circuit().export("circuit", "qiskit")
counts = qiskit_measure_and_count(qc_algo, shots=1024)
counts_readable = algo.decode_counts(counts)
self.assertEqual(counts_readable["Balanced"], 1024)

def test_deutschjozsa_constant(self):
f = """
def hash(k: Qint2) -> bool:
return False
"""
qf = qlassf(f, compiler="tweedledum")
algo = DeutschJozsa(qf)

qc_algo = algo.circuit().export("circuit", "qiskit")
counts = qiskit_measure_and_count(qc_algo, shots=1024)
counts_readable = algo.decode_counts(counts)
self.assertEqual(counts_readable["Constant"], 1024)

0 comments on commit efbf288

Please sign in to comment.