Skip to content

Commit

Permalink
added qft layer
Browse files Browse the repository at this point in the history
  • Loading branch information
01110011011101010110010001101111 committed Aug 4, 2023
1 parent 094991a commit 625126e
Showing 1 changed file with 109 additions and 0 deletions.
109 changes: 109 additions & 0 deletions torchquantum/layer/layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
SOFTWARE.
"""

import torch
import torch.nn as nn
import torchquantum as tq
import torchquantum.functional as tqf
Expand Down Expand Up @@ -49,6 +50,7 @@
"CXCXCXLayer",
"SWAPSWAPLayer",
"RXYZCXLayer0",
"QFTLayer",
]


Expand Down Expand Up @@ -914,6 +916,113 @@ def build_layers(self):
return layers_all


class QFTLayer(tq.QuantumModule):
def __init__(
self,
n_wires: int = None,
wires: Iterable = None,
add_swaps: bool = True,
inverse: bool = False,
):
"""
Constructs a Quantum Fourier Transform (QFT) layer
Args:
n_wires (int): Number of wires for the QFT as an integer
wires (Iterable): Wires to perform the QFT as an Iterable
add_swaps (bool): Whether or not to add the final swaps in a boolean format
inverse (bool): Whether to create an inverse QFT layer in a boolean format
"""
super().__init__()

assert n_wires is not None or wires is not None

if n_wires is None:
self.n_wires = len(wires)

if wires is None:
wires = range(n_wires)

self.n_wires = n_wires
self.wires = wires
self.add_swaps = add_swaps

if inverse:
self.gates_all = self.build_inverse_circuit()
else:
self.gates_all = self.build_circuit()

def build_circuit(self):
"""Construct a QFT circuit."""

operation_list = nn.ModuleList()

# add the H and CU1 gates
for top_wire in range(self.n_wires):
operation_list.append({"name": "hadamard", "wires": self.wires[top_wire]})
for wire in range(top_wire + 1, self.n_wires):
lam = torch.pi / (2 ** (wire - top_wire))
operation_list.append(
{
"name": "cu1",
"params": lam,
"wires": [self.wires[wire], self.wires[top_wire]],
}
)

# add swaps if specified
if self.add_swaps:
for wire in range(self.n_wires // 2):
operation_list.append(
{
"name": "swap",
"wires": [
self.wires[wire],
self.wires[self.n_wires - wire - 1],
],
}
)

return tq.QuantumModule.from_op_history(operation_list)

def build_inverse_circuit(self):
"""Construct the inverse of a QFT circuit."""

operation_list = []

# add swaps if specified
if self.add_swaps:
for wire in range(self.n_wires // 2):
operation_list.append(
{
"name": "swap",
"wires": [
self.wires[wire],
self.wires[self.n_wires - wire - 1],
],
}
)

# add the CU1 and H gates
for top_wire in range(self.n_wires)[::-1]:
for wire in range(top_wire + 1, self.n_wires)[::-1]:
lam = -torch.pi / (2 ** (wire - top_wire))
operation_list.append(
{
"name": "cu1",
"params": lam,
"wires": [self.wires[wire], self.wires[top_wire]],
}
)
operation_list.append({"name": "hadamard", "wires": self.wires[top_wire]})

return tq.QuantumModule.from_op_history(operation_list)

@tq.static_support
def forward(self, q_device: tq.QuantumDevice):
self.gates_all(q_device)


layer_name_dict = {
"u3cu3_0": U3CU3Layer0,
"cu3_0": CU3Layer0,
Expand Down

0 comments on commit 625126e

Please sign in to comment.