Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How-to: Quantum Arithmetic #1229

Closed
wants to merge 45 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
d29d6d7
first commit howto arithmetic
gmlejarza Oct 4, 2024
6e89bb1
Update demonstrations/tutorial_how_to_use_arithmetic_operators.py
KetpuntoG Oct 4, 2024
eabb5e8
cleaning code
KetpuntoG Oct 4, 2024
d7c6117
Apply suggestions from code review
KetpuntoG Oct 4, 2024
464cb64
suggestions from code review
gmlejarza Oct 7, 2024
56fc617
some suggestions
KetpuntoG Oct 7, 2024
b8997a1
Update tutorial_how_to_use_arithmetic_operators.py
KetpuntoG Oct 7, 2024
5893c0b
style and rendering changes
gmlejarza Oct 7, 2024
ca722ae
typo
KetpuntoG Oct 7, 2024
c3fdbbc
link for OutPoly
gmlejarza Oct 9, 2024
513a1a5
Immediate suggestions from code review
gmlejarza Oct 10, 2024
c8725b9
adressing first suggestions from code review
gmlejarza Oct 10, 2024
0ca2526
feedback from JM
gmlejarza Oct 14, 2024
ddb8b06
typo code
gmlejarza Oct 14, 2024
ddc8a90
adding plot of Adder
gmlejarza Oct 15, 2024
937f8a7
fix wires for Poly
gmlejarza Oct 15, 2024
8aad2e2
modulo explanation
gmlejarza Oct 15, 2024
a5b4540
suggestions from code review
gmlejarza Oct 17, 2024
d16d951
typo work_wires
gmlejarza Oct 17, 2024
9b8f24f
fixing adder with prepare state
gmlejarza Oct 17, 2024
0a176f8
typo circuit draw
gmlejarza Oct 17, 2024
006891c
suggestions from code review
gmlejarza Oct 24, 2024
30ba6a7
Apply suggestions from code review
gmlejarza Oct 28, 2024
e49d8c8
suggestions from code review
gmlejarza Oct 28, 2024
749cfa7
undo changes in Makefile
gmlejarza Oct 28, 2024
c10af36
fix rendering
gmlejarza Oct 29, 2024
3c7299a
suggestions and thumbnails
gmlejarza Oct 30, 2024
e5aa5b2
fix rendering
gmlejarza Oct 30, 2024
d5ca1a0
fix one reference
gmlejarza Oct 30, 2024
0357693
fix references
gmlejarza Oct 30, 2024
1b4a19d
new image and change w
KetpuntoG Oct 30, 2024
0e20b08
Apply suggestions from code review
gmlejarza Oct 31, 2024
e700f12
more suggestions
gmlejarza Oct 31, 2024
4b8e675
Apply suggestions from code review
gmlejarza Nov 4, 2024
a0ea1c4
adding related demo
gmlejarza Nov 4, 2024
cbfd3a5
renaming files and small wording
gmlejarza Nov 4, 2024
b27cf8f
bug in json name
gmlejarza Nov 4, 2024
213a955
small rename json
gmlejarza Nov 4, 2024
0dd30d6
tutorial_
KetpuntoG Nov 4, 2024
fbddd21
Merge branch 'dev' into arith_howto
ikurecic Nov 5, 2024
5c913ca
updating metadata
ikurecic Nov 5, 2024
5574357
cropping main file
ikurecic Nov 5, 2024
573a077
adjusting title
ikurecic Nov 5, 2024
3628c7a
adjusting formatting
ikurecic Nov 5, 2024
17c2f32
empty commit
KetpuntoG Nov 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"title": "How-to use Quantum Arithmetic Operators",
gmlejarza marked this conversation as resolved.
Show resolved Hide resolved
"authors": [
{
"id": "gmlejarza"
},
{
"id": "KetPuntoG"
}
],
"dateOfPublication": "2024-10-01T00:00:00+00:00",
"dateOfLastModification": "2024-10-01T00:00:00+00:00",
gmlejarza marked this conversation as resolved.
Show resolved Hide resolved
"categories": [
"Quantum Computing",
"Algorithms"
],
gmlejarza marked this conversation as resolved.
Show resolved Hide resolved
"tags": [],
"previewImages": [
{
"type": "thumbnail",
"uri": "/_static/demo_thumbnails/regular_demo_thumbnails/thumbnail_qnn_multivariate_regression.png"
},
{
"type": "large_thumbnail",
"uri": "/_static/demo_thumbnails/large_demo_thumbnails/thumbnail_large_qnn_multivariate_regression.png"
}
],
"seoDescription": "Learn how to use the quantum arithmetic operators of Pennylane.",
"doi": "",
"canonicalURL": "/qml/demos/tutorial_how_to_use_arithmetic_operators",
ikurecic marked this conversation as resolved.
Show resolved Hide resolved
"references": [
{
"id": "demo_qft_arith",
"type": "other",
"title": "Basic arithmetic with the quantum Fourier transform (QFT)",
"authors": "Guillermo Alonso",
"year": "2024",
"publisher": "",
"url": "https://pennylane.ai/qml/demos/tutorial_qft_arithmetics/"
}
],
"basedOnPapers": [],
"referencedByPapers": [],
"relatedContent": [
{
"type": "demonstration",
"id": "tutorial_qft_arithmetics",
"weight": 1.0
}
]
}
228 changes: 228 additions & 0 deletions demonstrations/tutorial_how_to_use_arithmetic_operators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
r"""
How-to use Quantum Arithmetic Operators
=======================================
gmlejarza marked this conversation as resolved.
Show resolved Hide resolved

Classical computers handle arithmetic operations like addition, subtraction, multiplication, and exponentiation with ease, thanks to decades of development. For instance, you can multiply two numbers on your phone in milliseconds!

gmlejarza marked this conversation as resolved.
Show resolved Hide resolved
In contrast, performing the same tasks on quantum computers isn't as straightforward. While they can excel at solving certain problems faster than classical computers, basic arithmetic isn't their strongest point. So why do we want to do quantum arithmetic anyway?

Well, quantum arithmetic isn't necessarily “better” at basic operations, but it becomes essential when it serves as a part of a more complex quantum algorithm. For example:

1. In Shor's algorithm for factoring large numbers, quantum arithmetic is crucial for performing modular exponentiation in order to execute the algorithm efficiently.

2. Grover's algorithm might need to use quantum arithmetic to construct oracles that help in speeding up search problems, as shown in [#qft_arith_demo]_.
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved

3. Loading functions into quantum computers, which might require several quantum arithmetic operations.

These arithmetic operations are like building blocks. Alone, they might not offer a speedup, but when incorporated into larger algorithms, they enable the kind of powerful computations that quantum computers are designed for.

With PennyLane, you'll see how easy it is to build these quantum arithmetic operations and use them as subroutines in your quantum algorithms!

gmlejarza marked this conversation as resolved.
Show resolved Hide resolved

Loading a function :math:`f(x, y)`
gmlejarza marked this conversation as resolved.
Show resolved Hide resolved
----------------------------------

In this how-to guide, we will show how we can apply a polynomial function in a quantum computer using basic arithmetic.
We will use as an example the function :math:`f(x,y)=a+b\cdot x+c\cdot y + d \cdot xy ` where the variables and the coefficients
are integer values. We will take the values :math:`a = 4`, :math:`b = 5`,:math:`c = 3` and :math:`d = 3`, defining the desired operator as:
gmlejarza marked this conversation as resolved.
Show resolved Hide resolved

.. math::

U|x\rangle |y\rangle |0\rangle = |x\rangle |y\rangle |4 + 5x + 3y + 3xy\rangle,

where :math:`x` and :math:`y` are the binary representations of the integers on which we want to apply the function.

gmlejarza marked this conversation as resolved.
Show resolved Hide resolved

InPlace and OutPlace Operations
-------------------------------

We can load the target function into the quantum computer using different quantum arithmetic operations.
We will break down into pieces. We'll do a step by step load of the function :math:`f(x, y)`.
gmlejarza marked this conversation as resolved.
Show resolved Hide resolved

First let's do the necessary imports, give the values to the constants :math:`a,b,c,d` and define the registers:
"""

import pennylane as qml

a, b, c, d = 4, 5, 3, 3

# we indicate the name of the registers and their number of qubits
wires = qml.registers({"x": 4, "y":4, "output":5,"work_wires": 4})

######################################################################
# We will start off building the initial quantum circuit

def prepare_initial_state(x,y):
ikurecic marked this conversation as resolved.
Show resolved Hide resolved
qml.BasisState(x, wires=wires["x"])
qml.BasisState(y, wires=wires["y"])


dev = qml.device("default.qubit", shots=1)
@qml.qnode(dev)
def circuit(x,y):
prepare_initial_state(x, y)
return [qml.sample(wires=wires[name]) for name in ["x", "y", "output"]]
gmlejarza marked this conversation as resolved.
Show resolved Hide resolved

######################################################################
# We can now check that this circuit performs the correct initialization by setting example values
# for :math:`x`, and :math:`y` such as :math:`x=1` and :math:`y=4`. In general, the variables :math:`x` and :math:`y` can represent any
# quantum state, but in this how-to they will be the quantum states [0 0 0 1] and [0 1 0 0] which represent the
# numbers 1 and 4 respectively.

output = circuit(x=1,y=4)

print("x register: ", output[0])
print("y register: ", output[1])
print("output register: ", output[2])


######################################################################
# Now, we can introduce the first quantum arithmetic operation to load :math:`f(x, y)`. The first step will be
# to load the constant :math:`a = 4` by using the Inplace addition operator :class:`~.pennylane.Adder`:
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved

@qml.qnode(dev)
def circuit(x,y):

prepare_initial_state(x, y) # |x> |y> |0>
qml.Adder(a, wires["output"]) # |x> |y> |4>

return qml.sample(wires=wires["output"])

print(circuit(x=1,y=4))

######################################################################
# We obtained the state [0 1 0 0], i.e. :math:`a=4`, as expected!
#
# The next step will be to add the term :math:`3xy` by using the
# Inplace and Outplace multiplication operators, :class:`~.pennylane.Multiplier` and :class:`~.pennylane.OutMultiplier` respectively.
# To do this, we first turn :math:`|x\rangle` into :math:`|3x\rangle` and then multiply it by :math:`|y\rangle`.

def adding_3xy():
# |x> ---> |3x>
qml.Multiplier(d, wires["x"], work_wires=wires["work_wires"])

# |3x>|y>|0> ---> |3x>|y>|3xy>
gmlejarza marked this conversation as resolved.
Show resolved Hide resolved
qml.OutMultiplier(wires["x"], wires["y"], wires["output"])

# We return the x-register to its original value
# |3x>|y>|3xy> ---> |x>|y>|3xy>
qml.adjoint(qml.Multiplier)(d, wires["x"], work_wires=wires["work_wires"])

@qml.qnode(dev)
def circuit(x,y):

prepare_initial_state(x, y) # |x> |y> |0>
qml.Adder(a, wires["output"]) # |x> |y> |4>
adding_3xy() # |x> |y> |3 + 3xy>

return qml.sample(wires=wires["output"])

print(circuit(x=1,y=4))

gmlejarza marked this conversation as resolved.
Show resolved Hide resolved
######################################################################
#Nice! The state [1 0 0 0 0] represents :math:`4+3\cdot xy =16`.
#
#The last step will involve to load the monomial terms :math:`5x` and math:`3y` by using
# the OutPlace addition operator :class:`~.pennylane.OutAdder` and the :class:`~.pennylane.Multiplier` previously employed.
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved

def adding_5x_3y():

# |x>|y> ---> |5x>|3y>
qml.Multiplier(b, wires["x"], work_wires=wires["work_wires"])
qml.Multiplier(c, wires["y"], work_wires=wires["work_wires"])

# |5x>|3y>|0> ---> |5x>|3y>|5x + 3y>
qml.OutAdder(wires["x"], wires["y"], wires["output"])

# We return the x and y registers to its original value
# |5x>|3y>|5x + 3y> ---> |x>|y>|5x + 3y>
qml.adjoint(qml.Multiplier)(b, wires["x"], work_wires=wires["work_wires"])
qml.adjoint(qml.Multiplier)(c, wires["y"], work_wires=wires["work_wires"])


@qml.qnode(dev)
def circuit(x,y):

prepare_initial_state(x, y) # |x> |y> |0>
qml.Adder(a, wires["output"]) # |x> |y> |4>
adding_3xy() # |x> |y> |4 + 3xy>
adding_5x_3y() # |x> |y> |4 + 5x + 3y + 3xy>


return qml.sample(wires=wires["output"])

print(circuit(x=1,y=4))

######################################################################
# The result obtained doesn't look quite right, since one would expect to obtain :math:`f(x=1,y=4)=4+ 5\cdot1+3\cdot4+ 3 \cdot 1 \cdot 4=33`...
# Could you guess what is going on?
#
# What's happening here is that we're running into overflow. The number 33 is too large for the number of wires we have defined in
# `wires[output]`. With 5 wires, we can represent numbers up to :math:`2^5=32`. Any number larger than that gets reduced to its modulo with
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved
# respect to :math:`2^5`. We have to keep in mind that all the quantum arithmetic is modular. So, every operation we perform is with respect
# to a given modulo that can be set by the user, but by default will be :math:`mod=2^{\text{len(wires)}}`.
#
# To fix this and get the correct result :math:`f(x=1,y=4)=33`, the simplest solution is to redefine the registers
# adding one more wire to the output.

wires = qml.registers({"x": 4, "y": 4, "output": 6,"work_wires": 4})
print(circuit(x=1, y=4))

######################################################################
# Now we get the correct result :math:`f(x=1,y=4)=33`!
gmlejarza marked this conversation as resolved.
Show resolved Hide resolved

######################################################################
# Using OutPoly
gmlejarza marked this conversation as resolved.
Show resolved Hide resolved
# ------------------------------------------
# In the last section, we showed how to use different arithmetic operations to load
# a function onto a quantum computer. But what if I told you there’s an easier way to do all this using just one
# PennyLane function that handles the arithmetic for you? Pretty cool, right? I’m talking about :class:`~.pennylane.OutPoly`.
# This handy operator lets you load polynomials directly into quantum states, taking care of all the arithmetic in one go.
# Let’s check out how to load a function like :math:`f(x, y)` using :class:`~.pennylane.OutPoly`!
#
# Let's first start by explicitly defining our function:

def f(x, y):
return a+b*x+c*y+d*x*y

######################################################################
# Now, let's load it into a quantum circuit!

######################################################################

@qml.qnode(dev)
def circuit_with_Poly(x,y):

prepare_initial_state(x, y)
#qml.OutPoly(f, registers_wires=[wires["x"], wires["y"], wires["output"]])

return qml.sample(wires = wires["output"])

print(circuit_with_Poly(x=1,y=4))
gmlejarza marked this conversation as resolved.
Show resolved Hide resolved

######################################################################
# Eureka! We’ve just seen how much easier it can be to implement arithmetic operations in one step.
# Now, it's up to you to decide, depending on the problem you're tackling, whether to go for the versatility
# of defining your own arithmetic operations or the convenience of using the :class:`~.pennylane.OutPoly` function.

######################################################################
# Conclusions
# ------------------------------------------
# In conclusion, understanding and implementing quantum arithmetic is a key step toward unlocking the full potential
# of quantum computing. While it may not replace classical efficiency for simple tasks, its role in complex algorithms
KetpuntoG marked this conversation as resolved.
Show resolved Hide resolved
# is undeniable. By leveraging tools like `qml.OutPoly`, you can streamline the coding of your quantum algorithms. So,
# whether you choose to customize your arithmetic operations or take advantage of the built-in convenience offered by PennyLane
# operators, you're now equipped to tackle exciting quantum challenges ahead!
#
# References
# ----------
#
# .. [#demo_qft_arith]
#
# Guillermo Alonso
# "Basic arithmetic with the quantum Fourier transform (QFT)",
# `Pennylane: Basic arithmetic with the quantum Fourier transform (QFT) <https://pennylane.ai/qml/demos/tutorial_qft_arithmetics/>`__, 2024
#
# About the authors
# -----------------

Loading