Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into QAOA_clean_fourier
Browse files Browse the repository at this point in the history
  • Loading branch information
Nik-SteinFraunh committed Nov 15, 2024
2 parents eda3649 + 0491a76 commit 3766691
Show file tree
Hide file tree
Showing 16 changed files with 439 additions and 384 deletions.
6 changes: 3 additions & 3 deletions documentation/source/reference/Backend Interface/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ This class is a wrapper for the VirtualBackend to quickly integrate Qiskit backe

::

from qiskit import Aer
from qiskit_aer import AerSimulator
from qrisp.interface import QiskitBackend
qiskit_backend = Aer.get_backend('qasm_simulator')
vrtl_qasm_sim = QiskitBackend(qiskit_backend)
qiskit_backend = AerSimulator()
vrtl_aer_sim = QiskitBackend(qiskit_backend)

Naturally, this also works for non-simulator Qiskit backends.

Expand Down
2 changes: 1 addition & 1 deletion src/qrisp/alg_primitives/arithmetic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
********************************************************************************/
"""


from qrisp.alg_primitives.arithmetic.comparisons import *
from qrisp.alg_primitives.arithmetic.SBP_arithmetic import *
from qrisp.alg_primitives.arithmetic.ripple_division import *
from qrisp.alg_primitives.arithmetic.ripple_mult import *
from qrisp.alg_primitives.arithmetic.matrix_multiplication import *
from qrisp.alg_primitives.arithmetic.modular_arithmetic import *
from qrisp.alg_primitives.arithmetic.adders import *
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,20 @@ def montgomery_red(t, a, b, N, m, permeable_if_zero = False):
# Perform Montgomery reduction
t, u = QREDC(t, N, m)

# Perform the uncomputation as described in the paper
for k in range(len(a)):
with control(a[k]):
t.inpl_adder(-((2**k*b))*modinv(N, 2**(m+1)), u)
if isinstance(b, QuantumFloat):
from qrisp.alg_primitives.arithmetic import inpl_q_int_mult, q_int_mult

inpl_q_int_mult(u, N%(2**(m+1)), inpl_adder = t.inpl_adder)

with invert():
q_int_mult(a, b, inpl_adder = t.inpl_adder, target_qf = u)

else:
# Perform the uncomputation as described in the paper
for k in range(len(a)):
with control(a[k]):
t.inpl_adder(-((2**k*b))*modinv(N, 2**(m+1)), u)

if permeable_if_zero:
# cx(t[0], u[-1])
pass
Expand Down Expand Up @@ -402,4 +411,37 @@ def semi_cl_inpl_mult(a, X, ctrl = None, treat_invalid = False):
a.__class__ = QuantumModulus
reduced.delete(verify = True)

return a
return a

def montgomery_mod_mul(a, b, output_qg = None):

m = int(np.ceil(np.log2((a.modulus-1)**2)+1)) - a.size

from qrisp import h, merge, QFT, q_int_mult
if a.modulus != b.modulus:
raise Exception("Tried to multiply two QuantumModulus with differing modulus")

if output_qg is None:
t = QuantumFloat(a.size + m, signed = True)
else:
if output_qg.modulus != a.modulus:
raise Exception("Output QuantumModulus has incompatible modulus")

merge(output_qg.qs, a.qs)
output_qg.extend(m, 0)
output_qg.add_sign()
output_qg.reg.insert(0, output_qg.reg.pop(-1))

t = output_qg

t = q_int_mult(a, b, target_qf = t, inpl_adder = a.inpl_adder)

from qrisp import QuantumModulus
t.__class__ = QuantumModulus
t.modulus = a.modulus
t.m = (a.m + b.m)
t.inpl_adder = a.inpl_adder

t = montgomery_red(t, a, b, a.modulus, m)

return t
74 changes: 45 additions & 29 deletions src/qrisp/alg_primitives/arithmetic/ripple_mult.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,55 @@
"""


from qrisp import cx, x
from qrisp.alg_primitives.arithmetic import create_output_qf, inpl_add


def ripple_mult(factor_1, factor_2):
from qrisp import cx, x, control
from qrisp.alg_primitives.arithmetic.adders import fourier_adder
from qrisp.qtypes.quantum_float import QuantumFloat

def q_int_mult(factor_1, factor_2, inpl_adder = fourier_adder, target_qf = None):

if factor_1.size < factor_2.size:
factor_1, factor_2 = factor_2, factor_1


if factor_1.signed or factor_2.signed:
raise Exception("Signed ripple multiplication currently not supported")

s = create_output_qf([factor_1, factor_2], op="mul")

n = factor_1.size - int(factor_1.signed)

factor_2.exp_shift(n)

s.init_from(factor_2)

factor_2.exp_shift(-n)

n = factor_1.size-1
if target_qf is None:
s = QuantumFloat(factor_1.size + factor_2.size + 1,
exponent = factor_1.exponent + factor_2.exponent)
for i in range(factor_2.size):
cx(factor_2[i], s[i+1+n])

else:
target_qf.extend(1, 0)
s = target_qf
inpl_adder(factor_2[:s.size-n-1], s[n+1:])

x(s)

inpl_add(s, factor_2)

for i in range(n):
cx(factor_1[i], s)

inpl_add(s, factor_2)

cx(factor_1[i], s)
factor_2.exp_shift(1)

inpl_adder(factor_2, s)

cx(factor_1[0], s)
for i in range(factor_1.size):

inpl_adder(factor_2[:len(s)-i], s[i:])

if i != factor_1.size-1:
pass
cx(factor_1[i], factor_1[i+1])
cx(factor_1[i+1], s)
cx(factor_1[i], factor_1[i+1])

cx(factor_1[-1], s)
x(s)

factor_2.exp_shift(-n)
s.exp_shift(-1)
s.reduce(s[0], verify = False)

return s

def inpl_q_int_mult(operand, cl_int, inpl_adder = fourier_adder):
if not cl_int%2:
raise Exception("In-place multiplication with even integers not supported")

for i in range(operand.size-1):
with control(operand[operand.size-2-i]):
inpl_adder(cl_int//2, operand[operand.size-1-i:])
15 changes: 8 additions & 7 deletions src/qrisp/alg_primitives/mcx_algs/circuit_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import numpy as np

from qrisp import QuantumCircuit, RYGate, CZGate, XGate, Instruction
from qrisp import QuantumCircuit, CZGate, XGate, Instruction

def ctrl_state_wrap(qc, ctrl_state):
res = qc.copy()
Expand Down Expand Up @@ -51,19 +51,20 @@ def ctrl_state_wrap(qc, ctrl_state):
# Margolus gate as described here https://arxiv.org/abs/quant-ph/0312225 and
# here https://www.iccs-meeting.org/archive/iccs2022/papers/133530169.pdf
margolus_qc = QuantumCircuit(3)
G = RYGate(np.pi / 4)

margolus_qc.append(G, 2)
margolus_qc.sx(2)
margolus_qc.t(2)
margolus_qc.cx(1, 2)
margolus_qc.append(G, 2)
margolus_qc.t(2)
margolus_qc.cx(0, 2)

reduced_margolus_qc = margolus_qc.copy()
reduced_margolus_qc.sx_dg(2)

margolus_qc.append(G.inverse(), 2)
margolus_qc.t_dg(2)
margolus_qc.cx(1, 2)
margolus_qc.append(G.inverse(), 2)

margolus_qc.t_dg(2)
margolus_qc.sx_dg(2)

# Ancilla supported multi controlled X gates from https://arxiv.org/pdf/1508.03273.pdf
# and https://www.iccs-meeting.org/archive/iccs2022/papers/133530169.pdf
Expand Down
10 changes: 5 additions & 5 deletions src/qrisp/core/quantum_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,15 @@ def __init__(self, backend=None):
Examples
--------
We create a QuantumSession with the QASM simulator as default backend and
We create a QuantumSession with the Aer simulator as default backend and
register a QuantumFloat in it:
>>> from qiskit import Aer
>>> qasm_sim = Aer.get_backend("qasm_simulator")
>>> from qiskit_aer import AerSimulator
>>> aer_sim = AerSimulator()
>>> from qrisp.interface import QiskitBackend
>>> vrtl_qasm_sim = QiskitBackend(qasm_sim)
>>> vrtl_aer_sim = QiskitBackend(aer_sim)
>>> from qrisp import QuantumSession, QuantumFloat
>>> qs = QuantumSession(vrtl_qasm_sim)
>>> qs = QuantumSession(vrtl_aer_sim)
>>> qf = QuantumFloat(4, qs = qs)
Expand Down
12 changes: 6 additions & 6 deletions src/qrisp/interface/provider_backends/qiskit_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,19 @@ class QiskitBackend(VirtualBackend):
----------
backend : Qiskit backend object, optional
A Qiskit backend object, which runs QuantumCircuits. The default is
Aer.get_backend('qasm_simulator').
``AerSimulator()``.
port : int, optional
The port to listen. The default is 8079.
Examples
--------
We evaluate a QuantumFloat multiplication on the QASM-simulator.
We evaluate a :ref:`QuantumFloat` multiplication on the Aer simulator.
>>> from qrisp import QuantumFloat
>>> from qrisp.interface import QiskitBackend
>>> from qiskit import Aer
>>> example_backend = QiskitBackend(backend = Aer.get_backend('qasm_simulator'))
>>> from qiskit_aer import AerSimulator
>>> example_backend = QiskitBackend(backend = AerSimulator())
>>> qf = QuantumFloat(4)
>>> qf[:] = 3
>>> res = qf*qf
Expand All @@ -54,9 +54,9 @@ def __init__(self, backend=None, port=None):
if backend is None:

try:
from qiskit import Aer
from qiskit_aer import AerSimulator

backend = Aer.get_backend("qasm_simulator")
backend = AerSimulator()
except ImportError:
from qiskit.providers.basic_provider import BasicProvider

Expand Down
6 changes: 3 additions & 3 deletions src/qrisp/interface/qunicorn/backend_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class BackendServer:
--------
We create a server listening on the localhost IP address using a run function which
prints the token and queries the QASM-simulator. ::
prints the token and queries the Aer-simulator. ::
def run_func(qasm_str, shots):
Expand All @@ -83,8 +83,8 @@ def run_func(qasm_str, shots):
qiskit_qc = QuantumCircuit.from_qasm_str(qasm_str)
from qiskit import Aer
qiskit_backend = Aer.get_backend('qasm_simulator')
from qiskit_aer import AerSimulator
qiskit_backend = AerSimulator()
#Run Circuit on the Qiskit backend
return qiskit_backend.run(qiskit_qc, shots = shots).result().get_counts()
Expand Down
4 changes: 2 additions & 2 deletions src/qrisp/interface/virtual_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ def run_func(qasm_str, shots = 1000, token = ""):
print(qiskit_qc)
from qiskit import Aer
qiskit_backend = Aer.get_backend('qasm_simulator')
from qiskit_aer import AerSimulator
qiskit_backend = AerSimulator()
#Run Circuit on the Qiskit backend
return qiskit_backend.run(qiskit_qc, shots = shots).result().get_counts()
Expand Down
3 changes: 3 additions & 0 deletions src/qrisp/misc/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -1874,12 +1874,15 @@ def t_depth_indicator(op, epsilon):
"s",
"h",
"s_dg",
"sx",
"sx_dg",
"measure",
"reset",
"qb_alloc",
"qb_dealloc",
"barrier",
"gphase",

]:
return 0
elif op.name in ["rx", "ry", "rz", "p", "u1"]:
Expand Down
Loading

0 comments on commit 3766691

Please sign in to comment.