Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -66,26 +66,26 @@
we will work with. We define wires for input registers, the output register, and also additional ``work_wires`` that will be important when we later discuss the :class:`~.pennylane.Multiplier` operator.
"""

import pennylane as qml
import pennylane as qp

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

######################################################################
# Now, we write a circuit to prepare the state :math:`|x \rangle|y \rangle|0 \rangle`, which will be needed for the out-place
# operation, where we initialize specific values to :math:`x` and :math:`y`. Note that in this example we use computational basis states, but
# you could introduce any quantum state as input.

def product_basis_state(x=0,y=0):
qml.BasisState(x, wires=wires["x"])
qml.BasisState(y, wires=wires["y"])
qp.BasisState(x, wires=wires["x"])
qp.BasisState(y, wires=wires["y"])

dev = qml.device("default.qubit")
@qml.set_shots(1)
@qml.qnode(dev)
dev = qp.device("default.qubit")
@qp.set_shots(1)
@qp.qnode(dev)
def circuit(x,y):
product_basis_state(x, y)
return {name: qml.sample(wires=wires[name]) for name in ["x", "y", "output"]}
return {name: qp.sample(wires=wires[name]) for name in ["x", "y", "output"]}

######################################################################
# Since the arithmetic operations are deterministic, a single shot is enough to sample
Expand All @@ -109,22 +109,22 @@ def state_to_decimal(binary_array):
# Now we can implement an example for the :class:`~.pennylane.Adder` operator. We will add the integer :math:`5` to the ``wires["x"]`` register
# that stores the state :math:`|x \rangle=|1 \rangle`.

@qml.set_shots(1)
@qml.qnode(dev)
@qp.set_shots(1)
@qp.qnode(dev)
def circuit(x):

product_basis_state(x) # |x>
qml.Adder(5, wires["x"]) # |x+5>
qp.Adder(5, wires["x"]) # |x+5>

return qml.sample(wires=wires["x"])
return qp.sample(wires=wires["x"])

print(circuit(x=1), " (binary) ---> ", state_to_decimal(circuit(x=1)[0])," (decimal)")

######################################################################
# We obtained the result :math:`5+1=6`, as expected. At this point, it's worth taking a moment to look
# at the decomposition of the circuit into quantum gates and operators.

fig, _ = qml.draw_mpl(circuit, decimals = 2, style = "pennylane", level='device')(x=1)
fig, _ = qp.draw_mpl(circuit, decimals = 2, style = "pennylane", level='device')(x=1)
fig.show()

######################################################################
Expand All @@ -136,14 +136,14 @@ def circuit(x):
# Now, let's see an example for the :class:`~.pennylane.OutAdder` operator to add the states
# :math:`|x \rangle` and :math:`|y \rangle` to the output register.

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

product_basis_state(x, y) # |x> |y> |0>
qml.OutAdder(wires["x"], wires["y"], wires["output"]) # |x> |y> |x+y>
qp.OutAdder(wires["x"], wires["y"], wires["output"]) # |x> |y> |x+y>

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

print(circuit(x=2,y=3), " (binary) ---> ", state_to_decimal(circuit(x=2,y=3)[0]), " (decimal)")

Expand Down Expand Up @@ -172,14 +172,14 @@ def circuit(x,y):
# :class:`~.pennylane.Multiplier` operator. We will multiply the state :math:`|x \rangle=|2 \rangle` by
# the integer :math:`k=3`:

@qml.set_shots(1)
@qml.qnode(dev)
@qp.set_shots(1)
@qp.qnode(dev)
def circuit(x):

product_basis_state(x) # |x>
qml.Multiplier(3, wires["x"], work_wires=wires["work_wires"]) # |3x>
qp.Multiplier(3, wires["x"], work_wires=wires["work_wires"]) # |3x>

return qml.sample(wires=wires["x"])
return qp.sample(wires=wires["x"])

print(circuit(x=2), " (binary) ---> ", state_to_decimal(circuit(x=2)[0])," (decimal)")

Expand All @@ -189,14 +189,14 @@ def circuit(x):
# Now, let's look at an example using the :class:`~.pennylane.OutMultiplier` operator to multiply the states :math:`|x \rangle` and
# :math:`|y \rangle`, storing the result in the output register.

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

product_basis_state(x, y) # |x> |y> |0>
qml.OutMultiplier(wires["x"], wires["y"], wires["output"]) # |x> |y> |xy>
qp.OutMultiplier(wires["x"], wires["y"], wires["output"]) # |x> |y> |xy>

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

print(circuit(x=4,y=2), " (binary) ---> ", state_to_decimal(circuit(x=4,y=2)[0])," (decimal)")

Expand All @@ -205,14 +205,14 @@ def circuit(x,y):
# multiplication, respectively. The inverse of a quantum circuit can be implemented with the
# :func:`~.pennylane.adjoint` operator. Let's see an example of modular subtraction.

@qml.set_shots(1)
@qml.qnode(dev)
@qp.set_shots(1)
@qp.qnode(dev)
def circuit(x):

product_basis_state(x) # |x>
qml.adjoint(qml.Adder(3, wires["x"])) # |x-3>
qp.adjoint(qp.Adder(3, wires["x"])) # |x-3>

return qml.sample(wires=wires["x"])
return qp.sample(wires=wires["x"])

print(circuit(x=6), " (binary) ---> ", state_to_decimal(circuit(x=6)[0]), " (decimal)")

Expand Down Expand Up @@ -244,14 +244,14 @@ def circuit(x):

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

# |3x>|y>|0> ---> |3x>|y>|3xy>
qml.OutMultiplier(wires["x"], wires["y"], wires["output"])
qp.OutMultiplier(wires["x"], wires["y"], wires["output"])

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

######################################################################
# Then we need to add the term :math:`5x + 3y` to the output register, which can be done by using the
Expand All @@ -260,30 +260,30 @@ def adding_3xy():
def adding_5x_3y():

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

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

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

######################################################################
# Now we can combine all these circuits to implement the transformation by the polynomial :math:`f(x,y)= 4 + 3xy + 5 x+ 3 y`.

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

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

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

print(circuit(x=1,y=4), " (binary) ---> ", state_to_decimal(circuit(x=1,y=4)[0]), " (decimal)")

Expand All @@ -293,7 +293,7 @@ def circuit(x,y):
# At this point, it's interesting to consider what would happen if we had chosen a smaller number of wires for the output.
# For instance, if we had selected one wire fewer, we would have obtained the result :math:`33 \mod 2^5 = 1`.

wires = qml.registers({"x": 4, "y": 4, "output": 5,"work_wires": 4})
wires = qp.registers({"x": 4, "y": 4, "output": 5,"work_wires": 4})

print(circuit(x=1,y=4), " (binary) ---> ", state_to_decimal(circuit(x=1,y=4)[0]), " (decimal)")

Expand All @@ -318,18 +318,18 @@ def f(x, y):

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

wires = qml.registers({"x": 4, "y":4, "output":6})
@qml.set_shots(1)
@qml.qnode(dev)
wires = qp.registers({"x": 4, "y":4, "output":6})
@qp.set_shots(1)
@qp.qnode(dev)
def circuit_with_Poly(x,y):

product_basis_state(x, y) # |x> |y> |0>
qml.OutPoly(
qp.OutPoly(
f,
input_registers= [wires["x"], wires["y"]],
output_wires = wires["output"]) # |x> |y> |4 + 3xy + 5x + 3y>

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

print(circuit_with_Poly(x=1,y=4), " (binary) ---> ", state_to_decimal(circuit_with_Poly(x=1,y=4)[0]), " (decimal)")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"executable_stable": true,
"executable_latest": true,
"dateOfPublication": "2024-11-05T00:00:00+00:00",
"dateOfLastModification": "2025-10-15T00:00:00+00:00",
"dateOfLastModification": "2026-04-17T00:00:00+00:00",
"categories": [
"Quantum Computing",
"Algorithms",
Expand Down
44 changes: 22 additions & 22 deletions demonstrations_v2/tutorial_how_to_use_registers/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
# wires in each register:
#

import pennylane as qml
import pennylane as qp

register = qml.registers({"alice": 1, "bob": 2, "charlie": 3})
register = qp.registers({"alice": 1, "bob": 2, "charlie": 3})
print(register)

######################################################################
Expand All @@ -25,7 +25,7 @@
#
# You can also pass in a dictionary that has nested dictionaries as its values.

nested_register = qml.registers(
nested_register = qp.registers(
{
"all_registers": {
"alice": 1,
Expand Down Expand Up @@ -75,25 +75,25 @@

import numpy as np

swap_register = qml.registers({"auxiliary": 1, "psi": 3, "phi": 3})
swap_register = qp.registers({"auxiliary": 1, "psi": 3, "phi": 3})

dev = qml.device("default.qubit")
dev = qp.device("default.qubit")

@qml.qnode(dev)
@qp.qnode(dev)
def swap_test():
# Make "psi" and "phi" state orthogonal to each other
qml.RX(np.pi/2, swap_register["phi"][0])
qp.RX(np.pi/2, swap_register["phi"][0])

qml.Hadamard(swap_register["auxiliary"])
qp.Hadamard(swap_register["auxiliary"])
for i in range(len(swap_register["psi"])):
# We can use the union operation to assemble our registers on the fly
qml.CSWAP(
qp.CSWAP(
swap_register["auxiliary"]
| swap_register["psi"][i]
| swap_register["phi"][i]
)
qml.Hadamard(swap_register["auxiliary"])
return qml.expval(qml.Z(wires=swap_register["auxiliary"]))
qp.Hadamard(swap_register["auxiliary"])
return qp.expval(qp.Z(wires=swap_register["auxiliary"]))


print(swap_test())
Expand All @@ -109,23 +109,23 @@ def swap_test():
# "estimation" or "measurement" register, and the other is the state register where we apply our
# unitary operators :math:`U.` We can define these registers in PennyLane code:

register = qml.registers({"state": 4, "estimation": 6})
register = qp.registers({"state": 4, "estimation": 6})

######################################################################
# To build our unitary operator :math:`U,` there are a variety of options. We can opt to use a
# straight-forward block encoding, or choose to use a subroutine like qubitization. Let's opt for
# :class:`~.pennylane.Qubitization`, which means we have to define another preparation register.
# Our registers now look like this:

register = qml.registers({"state": 4, "estimation": 6, "prep": 4})
register = qp.registers({"state": 4, "estimation": 6, "prep": 4})

######################################################################
# Finally, let's define our Hamiltonian. We'll use the `transverse-field Ising model <https://pennylane.ai/datasets/qspin/transverse-field-ising-model>`_ from
# `PennyLane Datasets <https://pennylane.ai/datasets/>`_,
# but feel free to try this with any other Hamiltonian.


[dataset] = qml.data.load(
[dataset] = qp.data.load(
"qspin", sysname="Ising", periodicity="open", lattice="chain", layout="1x4"
)
H = dataset.hamiltonians[0]
Expand All @@ -140,25 +140,25 @@ def swap_test():
######################################################################
# With this, we can now define our QPE circuit:

dev = qml.device("lightning.qubit", wires=14)
dev = qp.device("lightning.qubit", wires=14)

@qml.qnode(dev)
@qp.qnode(dev)
def circuit():
# Initialize state register to initial state
qml.StatePrep(initial_state, wires=register["state"])
qp.StatePrep(initial_state, wires=register["state"])

# Apply Hadamard gate to all wires in estimation register
for wire in register["estimation"]:
qml.Hadamard(wires=wire)
qp.Hadamard(wires=wire)

qml.ControlledSequence(
qml.Qubitization(H, register["prep"]),
qp.ControlledSequence(
qp.Qubitization(H, register["prep"]),
control=register["estimation"],
)

qml.adjoint(qml.QFT)(wires=register["estimation"])
qp.adjoint(qp.QFT)(wires=register["estimation"])

return qml.probs(wires=register["estimation"])
return qp.probs(wires=register["estimation"])

######################################################################
# We'll run our circuit and do some post-processing to get the energy eigenvalue:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"executable_stable": true,
"executable_latest": true,
"dateOfPublication": "2024-09-05T00:00:00+00:00",
"dateOfLastModification": "2025-09-22T15:48:14+00:00",
"dateOfLastModification": "2026-04-17T15:48:14+00:00",
"categories": [
"Getting Started",
"How-to"
Expand Down
Loading
Loading