Skip to content

Commit

Permalink
Merge pull request #91 from eclipse-qrisp/switch_case_integration
Browse files Browse the repository at this point in the history
implemented qswitch
  • Loading branch information
positr0nium authored Nov 15, 2024
2 parents c796a5c + 7aafa36 commit 199fb70
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/qrisp/alg_primitives/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@
from qrisp.alg_primitives.arithmetic import *
from qrisp.alg_primitives.iterable_processing import *
from qrisp.alg_primitives.dicke_state_prep import *
from qrisp.alg_primitives.switch_case import *
73 changes: 73 additions & 0 deletions src/qrisp/alg_primitives/switch_case.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""
\********************************************************************************
* Copyright (c) 2023 the Qrisp authors
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License, v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is
* available at https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
"""

from qrisp.core.gate_application_functions import h
from qrisp.alg_primitives.qft import QFT
from qrisp.core import QuantumArray
from qrisp.qtypes import QuantumBool
from qrisp.environments import conjugate, control
from qrisp.alg_primitives import demux

def qswitch(operand, case, case_function_list, method = "sequential"):
"""
Executes a switch - case statement distinguishing between a list of
given in-place functions.
Parameters
----------
operand : QuantumVariable
The QuantumVariable to operate on.
case : QuantumFloat
The QuantumFloat indicating which functions to execute.
case_function_list : list[callable]
The list of functions which are executed depending on the case.
"""

if method == "sequential":

for i in range(len(case_function_list)):
with i == case:
case_function_list[i](operand)

elif method == "parallel":

# Idea: Use demux function to move operand and enabling bool into QuantumArray
# to execute cases in parallel.
case_amount = len(case_function_list)

# This QuantumArray acts as an addressable QRAM via the demux function
enable = QuantumArray(qtype = QuantumBool(), shape = (case_amount,))
enable[0].flip()

qa = QuantumArray(qtype = operand, shape = ((case_amount,)))

with conjugate(demux)(operand, case, qa, parallelize_qc = True):
with conjugate(demux)(enable[0], case, enable, parallelize_qc = True):
for i in range(case_amount):
with control(enable[i]):
case_function_list[i](qa[i])

qa.delete()

enable[0].flip()
enable.delete()

else:
raise Exception("Don't know compile method {method} for switch-case structure.")
53 changes: 53 additions & 0 deletions tests/test_qswitch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""
\********************************************************************************
* Copyright (c) 2023 the Qrisp authors
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License, v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is
* available at https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
"""

from qrisp import inpl_mult, h, QuantumFloat, qswitch, multi_measurement
def test_qswitch():

# Some sample case functions
def f0(x): x += 1
def f1(x): inpl_mult(x, 3, treat_overflow = False)
def f2(x): pass
def f3(x): h(x[1])
case_function_list = [f0, f1, f2, f3]

# Create operand and case variable
operand = QuantumFloat(4)
operand[:] = 1
case = QuantumFloat(2)
h(case)

# Execute switch_case function
qswitch(operand, case, case_function_list)

# Simulate
assert multi_measurement([case, operand]) == {(0, 2): 0.25, (1, 3): 0.25, (2, 1): 0.25, (3, 1): 0.125, (3, 3): 0.125}
# Yields {(0, 2): 0.25, (1, 3): 0.25, (2, 1): 0.25, (3, 1): 0.125, (3, 3): 0.125}

# Create operand and case variable
operand = QuantumFloat(4)
operand[:] = 1
case = QuantumFloat(2)
h(case)

# Execute switch_case function
qswitch(operand, case, case_function_list, method = "parallel")

# Simulate
assert multi_measurement([case, operand]) == {(0, 2): 0.25, (1, 3): 0.25, (2, 1): 0.25, (3, 1): 0.125, (3, 3): 0.125}
# Yields {(0, 2): 0.25, (1, 3): 0.25, (2, 1): 0.25, (3, 1): 0.125, (3, 3): 0.125}

0 comments on commit 199fb70

Please sign in to comment.