diff --git a/README.md b/README.md index 9105e0f8..d905eb03 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,19 @@
-
-
-
+
+
+
+
+
+
+
diff --git a/docs/source/api_layers.rst b/docs/source/api_layers.rst
new file mode 100644
index 00000000..18a6753c
--- /dev/null
+++ b/docs/source/api_layers.rst
@@ -0,0 +1,29 @@
+torchquantum.layers
+======================
+
+.. currentmodule:: torchquantum.layer
+
+Layers
+---------
+.. autosummary::
+ :toctree: generated
+ :template: classtemplate_controlflow.rst
+
+
+ QuantumModuleFromOps
+ TrainableOpAll
+ ClassicalInOpAll
+ FixedOpAll
+ TwoQAll
+ RandomLayer
+ RandomLayerAllTypes
+ Op1QAllLayer
+ RandomOp1All
+ Op2QAllLayer
+ Op2QButterflyLayer
+ Op2QDenseLayer
+ CXLayer
+ CXCXCXLayer
+ SWAPSWAPLayer
+ RXYZCXLayer0
+ QFTLayer
diff --git a/docs/source/api_operators.rst b/docs/source/api_operators.rst
index f8c607d3..7933fd01 100644
--- a/docs/source/api_operators.rst
+++ b/docs/source/api_operators.rst
@@ -1,7 +1,7 @@
torchquantum.operators
======================
-.. currentmodule:: torchquantum.operators
+.. currentmodule:: torchquantum.operator
Classes
---------
diff --git a/docs/source/index.rst b/docs/source/index.rst
index a1a4f08a..24f29897 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -5,6 +5,7 @@
api_torchquantum
api_functional
api_operators
+ api_layers
.. toctree::
:maxdepth: 1
diff --git a/examples/gradient_pruning/q_models.py b/examples/gradient_pruning/q_models.py
index 1073ac72..133993ef 100644
--- a/examples/gradient_pruning/q_models.py
+++ b/examples/gradient_pruning/q_models.py
@@ -154,7 +154,7 @@ def shift_and_run(
node.shift_this_step[idx] = True
elif self.pruning_method == "perlayer_pruning":
node.shift_this_step[:] = False
- idxs = torch.range(0, self.n_params - 1, dtype=int).view(
+ idxs = torch.arange(0, self.n_params, dtype=int).view(
self.n_qubits, self.n_layers
)
sampled_colums = self.colums
@@ -164,7 +164,7 @@ def shift_and_run(
self.colums %= self.n_layers
elif self.pruning_method == "perqubit_pruning":
node.shift_this_step[:] = False
- idxs = torch.range(0, self.n_params - 1, dtype=int).view(
+ idxs = torch.arange(0, self.n_params, dtype=int).view(
self.n_qubits, self.n_layers
)
sampled_rows = self.rows
diff --git a/examples/index.rst b/examples/index.rst
index e36da434..c9bd9c24 100644
--- a/examples/index.rst
+++ b/examples/index.rst
@@ -8,4 +8,6 @@ TorchQuantum Examples
param_shift_onchip_training/param_shift_onchip_training.ipynb
quantum_kernel_method/quantum_kernel_method.ipynb
quanvolution/quanvolution.ipynb
- superdense_coding/superdense_coding_torchquantum.ipynb
\ No newline at end of file
+ superdense_coding/superdense_coding_torchquantum.ipynb
+ qubit_rotation/TQ_Qubit_Rotation_Tutorial.ipynb
+
diff --git a/examples/superdense_coding/superdense_coding_torchquantum.ipynb b/examples/superdense_coding/superdense_coding_torchquantum.ipynb
index 3f53e91c..e4128624 100644
--- a/examples/superdense_coding/superdense_coding_torchquantum.ipynb
+++ b/examples/superdense_coding/superdense_coding_torchquantum.ipynb
@@ -502,7 +502,7 @@
"id": "nFC9-bqHbG2I"
},
"source": [
- "# References:\n",
+ "## References:\n",
"\n",
"[1] Bennett, C.H., Brassard, G., Crépeau, C., Jozsa, R., Peres, A. and Wootters, W.K., 1993. Teleporting an unknown quantum state via dual classical and Einstein-Podolsky-Rosen channels. Physical review letters, 70(13), p.1895.\n",
"\n",
diff --git a/test/layers/test_rotgate.py b/test/layers/test_rotgate.py
new file mode 100644
index 00000000..c69d5569
--- /dev/null
+++ b/test/layers/test_rotgate.py
@@ -0,0 +1,55 @@
+import torchquantum as tq
+import qiskit
+from qiskit import Aer, execute
+
+from torchquantum.util import (
+ switch_little_big_endian_matrix,
+ find_global_phase,
+)
+
+from qiskit.circuit.library import GR, GRX, GRY, GRZ
+import numpy as np
+
+all_pairs = [
+ {"qiskit": GR, "tq": tq.layer.GlobalR, "params": 2},
+ {"qiskit": GRX, "tq": tq.layer.GlobalRX, "params": 1},
+ {"qiskit": GRY, "tq": tq.layer.GlobalRY, "params": 1},
+ {"qiskit": GRZ, "tq": tq.layer.GlobalRZ, "params": 1},
+]
+
+ITERATIONS = 10
+
+# test each pair
+for pair in all_pairs:
+ # test 2-5 wires
+ for num_wires in range(2, 5):
+ # try multiple random parameters
+ for _ in range(ITERATIONS):
+ # generate random parameters
+ params = [
+ np.random.uniform(-2 * np.pi, 2 * np.pi) for _ in range(pair["params"])
+ ]
+
+ # create the qiskit circuit
+ qiskit_circuit = pair["qiskit"](num_wires, *params)
+
+ # get the unitary from qiskit
+ backend = Aer.get_backend("unitary_simulator")
+ result = execute(qiskit_circuit, backend).result()
+ unitary_qiskit = result.get_unitary(qiskit_circuit)
+
+ # create tq circuit
+ qdev = tq.QuantumDevice(num_wires)
+ tq_circuit = pair["tq"](num_wires, *params)
+ tq_circuit(qdev)
+
+ # get the unitary from tq
+ unitary_tq = tq_circuit.get_unitary(qdev)
+ unitary_tq = switch_little_big_endian_matrix(unitary_tq.data.numpy())
+
+ # phase?
+ phase = find_global_phase(unitary_tq, unitary_qiskit, 1e-4)
+
+ assert np.allclose(
+ unitary_tq * phase, unitary_qiskit, atol=1e-6
+ ), f"{pair} not equal with {params=}!"
diff --git a/torchquantum/layer/__init__.py b/torchquantum/layer/__init__.py
index a6c99385..ce5540cb 100644
--- a/torchquantum/layer/__init__.py
+++ b/torchquantum/layer/__init__.py
@@ -24,3 +24,4 @@
from .layers import *
from .nlocal import *
+from .general import *
diff --git a/torchquantum/layer/general.py b/torchquantum/layer/general.py
new file mode 100644
index 00000000..9857220a
--- /dev/null
+++ b/torchquantum/layer/general.py
@@ -0,0 +1,104 @@
+"""
+MIT License
+
+Copyright (c) 2020-present TorchQuantum Authors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+"""
+
+
+import torch
+import torchquantum as tq
+from torchquantum.layer.layers import (
+ LayerTemplate0,
+ Op1QAllLayer,
+ Op2QAllLayer,
+ RandomOp1All,
+)
+
+__all__ = [
+ "GlobalR",
+ "GlobalRX",
+ "GlobalRY",
+ "GlobalRZ",
+]
+
+
+class GlobalR(tq.QuantumModule):
+ """Layer Template for a Global R General Gate"""
+
+ def __init__(
+ self,
+ n_wires: int = 0,
+ theta: float = 0,
+ phi: float = 0,
+ ):
+ """Create the layer"""
+ super().__init__()
+ self.n_wires = n_wires
+ self.params = torch.tensor([[theta, phi]])
+
+ @tq.static_support
+ def forward(self, q_device, x=None):
+ for k in range(self.n_wires):
+ tq.R()(q_device, wires=k, params=self.params)
+
+
+class GlobalRX(GlobalR):
+ """Layer Template for a Global RX General Gate"""
+
+ def __init__(
+ self,
+ n_wires: int = 0,
+ theta: float = 0,
+ ):
+ """Create the layer"""
+ super().__init__(n_wires, theta, phi=0)
+
+
+class GlobalRY(GlobalR):
+ """Layer Template for a Global RY General Gate"""
+
+ def __init__(
+ self,
+ n_wires: int = 0,
+ theta: float = 0,
+ ):
+ """Create the layer"""
+ super().__init__(n_wires, theta, phi=torch.pi / 2)
+
+class GlobalRZ(tq.QuantumModule):
+ """Layer Template for a Global RZ General Gate"""
+
+ def __init__(
+ self,
+ n_wires: int = 0,
+ phi: float = 0,
+ ):
+ """Create the layer"""
+ super().__init__()
+ self.n_wires = n_wires
+ self.params = torch.tensor([[phi]])
+
+ @tq.static_support
+ def forward(self, q_device, x=None):
+ for k in range(self.n_wires):
+ tq.RZ()(q_device, wires=k, params=self.params)
+
+
diff --git a/torchquantum/layer/layers.py b/torchquantum/layer/layers.py
index 9d4e5f61..2f6aedec 100644
--- a/torchquantum/layer/layers.py
+++ b/torchquantum/layer/layers.py
@@ -53,6 +53,11 @@
"RXYZCXLayer0",
"U3CU3Layer0",
"QFTLayer",
+ "EntangleLinear",
+ "EntanglePairwise",
+ "EntangleFull",
+ "EntangleCircular",
+ "EntanglementLayer",
"SethLayer0",
]
@@ -60,10 +65,11 @@
class QuantumModuleFromOps(tq.QuantumModule):
"""Initializes a QuantumModuleFromOps instance.
- Args:
- ops (List[tq.Operation]): List of quantum operations.
+ Args:
+ ops (List[tq.Operation]): List of quantum operations.
+
+ """
- """
def __init__(self, ops):
super().__init__()
self.ops = tq.QuantumModuleList(ops)
@@ -72,13 +78,13 @@ def __init__(self, ops):
def forward(self, q_device: tq.QuantumDevice):
"""Performs the forward pass of the quantum module.
- Args:
- q_device (tq.QuantumDevice): Quantum device to apply the operations on.
+ Args:
+ q_device (tq.QuantumDevice): Quantum device to apply the operations on.
- Returns:
- None
+ Returns:
+ None
- """
+ """
self.q_device = q_device
for op in self.ops:
op(q_device)
@@ -113,18 +119,19 @@ def forward(self, q_device: tq.QuantumDevice):
class ClassicalInOpAll(tq.QuantumModule):
"""
- Quantum module that applies the same quantum operation to all wires of a quantum device,
- where the parameters of the operation are obtained from a classical input.
+ Quantum module that applies the same quantum operation to all wires of a quantum device,
+ where the parameters of the operation are obtained from a classical input.
- Args:
- n_gate (int): Number of gates.
- op (tq.Operator): Quantum operation to be applied.
+ Args:
+ n_gate (int): Number of gates.
+ op (tq.Operator): Quantum operation to be applied.
- Attributes:
- n_gate (int): Number of gates.
- gate_all (nn.ModuleList): List of quantum operations.
+ Attributes:
+ n_gate (int): Number of gates.
+ gate_all (nn.ModuleList): List of quantum operations.
+
+ """
- """
def __init__(self, n_gate: int, op: tq.Operator):
super().__init__()
self.n_gate = n_gate
@@ -135,19 +142,19 @@ def __init__(self, n_gate: int, op: tq.Operator):
@tq.static_support
def forward(self, q_device: tq.QuantumDevice, x):
"""
- Performs the forward pass of the classical input quantum operation module.
+ Performs the forward pass of the classical input quantum operation module.
- Args:
- q_device (tq.QuantumDevice): Quantum device to apply the operations on.
- x (torch.Tensor): Classical input of shape (batch_size, n_gate).
+ Args:
+ q_device (tq.QuantumDevice): Quantum device to apply the operations on.
+ x (torch.Tensor): Classical input of shape (batch_size, n_gate).
- Returns:
- None
+ Returns:
+ None
- Raises:
- AssertionError: If the number of gates is different from the number of wires in the device.
+ Raises:
+ AssertionError: If the number of gates is different from the number of wires in the device.
- """
+ """
# rx on all wires, assert the number of gate is the same as the number
# of wires in the device.
assert self.n_gate == q_device.n_wires, (
@@ -161,17 +168,18 @@ def forward(self, q_device: tq.QuantumDevice, x):
class FixedOpAll(tq.QuantumModule):
"""
- Quantum module that applies the same fixed quantum operation to all wires of a quantum device.
+ Quantum module that applies the same fixed quantum operation to all wires of a quantum device.
+
+ Args:
+ n_gate (int): Number of gates.
+ op (tq.Operator): Quantum operation to be applied.
- Args:
- n_gate (int): Number of gates.
- op (tq.Operator): Quantum operation to be applied.
+ Attributes:
+ n_gate (int): Number of gates.
+ gate_all (nn.ModuleList): List of quantum operations.
- Attributes:
- n_gate (int): Number of gates.
- gate_all (nn.ModuleList): List of quantum operations.
+ """
- """
def __init__(self, n_gate: int, op: tq.Operator):
super().__init__()
self.n_gate = n_gate
@@ -182,18 +190,18 @@ def __init__(self, n_gate: int, op: tq.Operator):
@tq.static_support
def forward(self, q_device: tq.QuantumDevice):
"""
- Performs the forward pass of the fixed quantum operation module.
+ Performs the forward pass of the fixed quantum operation module.
- Args:
- q_device (tq.QuantumDevice): Quantum device to apply the operations on.
+ Args:
+ q_device (tq.QuantumDevice): Quantum device to apply the operations on.
- Returns:
- None
+ Returns:
+ None
- Raises:
- AssertionError: If the number of gates is different from the number of wires in the device.
+ Raises:
+ AssertionError: If the number of gates is different from the number of wires in the device.
- """
+ """
# rx on all wires, assert the number of gate is the same as the number
# of wires in the device.
assert self.n_gate == q_device.n_wires, (
@@ -207,17 +215,18 @@ def forward(self, q_device: tq.QuantumDevice):
class TwoQAll(tq.QuantumModule):
"""
- Quantum module that applies a two-qubit quantum operation to adjacent pairs of wires in a quantum device.
+ Quantum module that applies a two-qubit quantum operation to adjacent pairs of wires in a quantum device.
- Args:
- n_gate (int): Number of adjacent pairs of wires.
- op (tq.Operator): Two-qubit quantum operation to be applied.
+ Args:
+ n_gate (int): Number of adjacent pairs of wires.
+ op (tq.Operator): Two-qubit quantum operation to be applied.
- Attributes:
- n_gate (int): Number of adjacent pairs of wires.
- op (tq.Operator): Two-qubit quantum operation.
+ Attributes:
+ n_gate (int): Number of adjacent pairs of wires.
+ op (tq.Operator): Two-qubit quantum operation.
+
+ """
- """
def __init__(self, n_gate: int, op: tq.Operator):
super().__init__()
self.n_gate = n_gate
@@ -272,28 +281,29 @@ def forward(self, q_device: tq.QuantumDevice, x):
class RandomLayer(tq.QuantumModule):
"""
- Quantum module that represents a random layer of quantum operations applied to specified wires.
+ Quantum module that represents a random layer of quantum operations applied to specified wires.
+
+ Args:
+ wires (int or Iterable[int]): Indices of the wires the operations are applied to.
+ n_ops (int): Number of random operations in the layer.
+ n_params (int): Number of parameters for each random operation.
+ op_ratios (list or float): Ratios determining the relative frequencies of different operation types.
+ op_types (tuple or tq.Operator): Types of random operations to be included in the layer.
+ seed (int): Seed for random number generation.
+ qiskit_compatible (bool): Flag indicating whether the layer should be compatible with Qiskit.
+
+ Attributes:
+ n_ops (int): Number of random operations in the layer.
+ n_params (int): Number of parameters for each random operation.
+ wires (list): Indices of the wires the operations are applied to.
+ n_wires (int): Number of wires.
+ op_types (list): Types of random operations included in the layer.
+ op_ratios (numpy.array): Ratios determining the relative frequencies of different operation types.
+ seed (int): Seed for random number generation.
+ op_list (tq.QuantumModuleList): List of random operations in the layer.
- Args:
- wires (int or Iterable[int]): Indices of the wires the operations are applied to.
- n_ops (int): Number of random operations in the layer.
- n_params (int): Number of parameters for each random operation.
- op_ratios (list or float): Ratios determining the relative frequencies of different operation types.
- op_types (tuple or tq.Operator): Types of random operations to be included in the layer.
- seed (int): Seed for random number generation.
- qiskit_compatible (bool): Flag indicating whether the layer should be compatible with Qiskit.
-
- Attributes:
- n_ops (int): Number of random operations in the layer.
- n_params (int): Number of parameters for each random operation.
- wires (list): Indices of the wires the operations are applied to.
- n_wires (int): Number of wires.
- op_types (list): Types of random operations included in the layer.
- op_ratios (numpy.array): Ratios determining the relative frequencies of different operation types.
- seed (int): Seed for random number generation.
- op_list (tq.QuantumModuleList): List of random operations in the layer.
+ """
- """
def __init__(
self,
wires,
@@ -344,15 +354,15 @@ def __init__(
def rebuild_random_layer_from_op_list(self, n_ops_in, wires_in, op_list_in):
"""
- Rebuilds a random layer from the given operation list.
- This method is used for loading a random layer from a checkpoint.
+ Rebuilds a random layer from the given operation list.
+ This method is used for loading a random layer from a checkpoint.
- Args:
- n_ops_in (int): Number of operations in the layer.
- wires_in (list): Indices of the wires the operations are applied to.
- op_list_in (list): List of operations in the layer.
+ Args:
+ n_ops_in (int): Number of operations in the layer.
+ wires_in (list): Indices of the wires the operations are applied to.
+ op_list_in (list): List of operations in the layer.
- """
+ """
self.n_ops = n_ops_in
self.wires = wires_in
@@ -423,20 +433,21 @@ def forward(self, q_device: tq.QuantumDevice):
class RandomLayerAllTypes(RandomLayer):
"""
- Random layer with a wide range of quantum gate types.
+ Random layer with a wide range of quantum gate types.
+
+ This class extends the `RandomLayer` class to include a variety of quantum gate types as options for the random layer.
- This class extends the `RandomLayer` class to include a variety of quantum gate types as options for the random layer.
+ Args:
+ wires (int or list): Indices of the wires the operations are applied to.
+ n_ops (int): Number of operations in the layer.
+ n_params (int): Number of parameters for each operation.
+ op_ratios (list): Ratios for selecting different types of operations.
+ op_types (tuple): Types of operations to include in the layer.
+ seed (int): Seed for the random number generator.
+ qiskit_compatible (bool): Flag indicating whether the layer should be Qiskit-compatible.
- Args:
- wires (int or list): Indices of the wires the operations are applied to.
- n_ops (int): Number of operations in the layer.
- n_params (int): Number of parameters for each operation.
- op_ratios (list): Ratios for selecting different types of operations.
- op_types (tuple): Types of operations to include in the layer.
- seed (int): Seed for the random number generator.
- qiskit_compatible (bool): Flag indicating whether the layer should be Qiskit-compatible.
+ """
- """
def __init__(
self,
wires,
@@ -491,14 +502,15 @@ def __init__(
class SimpleQLayer(tq.QuantumModule):
"""
- Simple quantum layer consisting of three parameterized gates applied to specific wires.
+ Simple quantum layer consisting of three parameterized gates applied to specific wires.
+
+ This class represents a simple quantum layer with three parameterized gates: RX, RY, and RZ. The gates are applied to specific wires in the quantum device.
- This class represents a simple quantum layer with three parameterized gates: RX, RY, and RZ. The gates are applied to specific wires in the quantum device.
+ Args:
+ n_wires (int): Number of wires in the quantum device.
- Args:
- n_wires (int): Number of wires in the quantum device.
+ """
- """
def __init__(self, n_wires):
super().__init__()
self.n_wires = n_wires
@@ -518,14 +530,15 @@ def forward(self, q_dev):
class CXLayer(tq.QuantumModule):
"""
- Quantum layer with a controlled-X (CX) gate applied to two specified wires.
+ Quantum layer with a controlled-X (CX) gate applied to two specified wires.
- This class represents a quantum layer with a controlled-X (CX) gate applied to two specified wires in the quantum device.
+ This class represents a quantum layer with a controlled-X (CX) gate applied to two specified wires in the quantum device.
- Args:
- n_wires (int): Number of wires in the quantum device.
+ Args:
+ n_wires (int): Number of wires in the quantum device.
+
+ """
- """
def __init__(self, n_wires):
super().__init__()
self.n_wires = n_wires
@@ -538,14 +551,15 @@ def forward(self, q_dev):
class CXCXCXLayer(tq.QuantumModule):
"""
- Quantum layer with a sequence of CX gates applied to three specified wires.
+ Quantum layer with a sequence of CX gates applied to three specified wires.
- This class represents a quantum layer with a sequence of CX gates applied to three specified wires in the quantum device.
+ This class represents a quantum layer with a sequence of CX gates applied to three specified wires in the quantum device.
- Args:
- n_wires (int): Number of wires in the quantum device.
+ Args:
+ n_wires (int): Number of wires in the quantum device.
+
+ """
- """
def __init__(self, n_wires):
super().__init__()
self.n_wires = n_wires
@@ -560,14 +574,15 @@ def forward(self, q_dev):
class SWAPSWAPLayer(tq.QuantumModule):
"""
- Quantum layer with a sequence of SWAP gates applied to two specified pairs of wires.
+ Quantum layer with a sequence of SWAP gates applied to two specified pairs of wires.
- This class represents a quantum layer with a sequence of SWAP gates applied to two specified pairs of wires in the quantum device.
+ This class represents a quantum layer with a sequence of SWAP gates applied to two specified pairs of wires in the quantum device.
- Args:
- n_wires (int): Number of wires in the quantum device.
+ Args:
+ n_wires (int): Number of wires in the quantum device.
+
+ """
- """
def __init__(self, n_wires):
super().__init__()
self.n_wires = n_wires
@@ -581,17 +596,18 @@ def forward(self, q_dev):
class Op1QAllLayer(tq.QuantumModule):
"""
- Quantum layer applying the same single-qubit operation to all wires.
+ Quantum layer applying the same single-qubit operation to all wires.
- This class represents a quantum layer that applies the same single-qubit operation to all wires in the quantum device.
+ This class represents a quantum layer that applies the same single-qubit operation to all wires in the quantum device.
- Args:
- op (tq.Operator): Single-qubit operation to be applied.
- n_wires (int): Number of wires in the quantum device.
- has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
- trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
+ Args:
+ op (tq.Operator): Single-qubit operation to be applied.
+ n_wires (int): Number of wires in the quantum device.
+ has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
+ trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
+
+ """
- """
def __init__(self, op, n_wires: int, has_params=False, trainable=False):
super().__init__()
self.n_wires = n_wires
@@ -608,21 +624,22 @@ def forward(self, q_device):
class Op2QAllLayer(tq.QuantumModule):
"""
- Quantum layer applying the same two-qubit operation to all pairs of adjacent wires.
- This class represents a quantum layer that applies the same two-qubit operation to all pairs of adjacent wires
- in the quantum device. The pairs of wires can be determined in a circular or non-circular pattern based on the
- specified jump.
-
- Args:
- op (tq.Operator): Two-qubit operation to be applied.
- n_wires (int): Number of wires in the quantum device.
- has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
- trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
- wire_reverse (bool, optional): Flag indicating if the order of wires in each pair should be reversed. Defaults to False.
- jump (int, optional): Number of positions to jump between adjacent pairs of wires. Defaults to 1.
- circular (bool, optional): Flag indicating if the pattern should be circular. Defaults to False.
+ Quantum layer applying the same two-qubit operation to all pairs of adjacent wires.
+ This class represents a quantum layer that applies the same two-qubit operation to all pairs of adjacent wires
+ in the quantum device. The pairs of wires can be determined in a circular or non-circular pattern based on the
+ specified jump.
+
+ Args:
+ op (tq.Operator): Two-qubit operation to be applied.
+ n_wires (int): Number of wires in the quantum device.
+ has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
+ trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
+ wire_reverse (bool, optional): Flag indicating if the order of wires in each pair should be reversed. Defaults to False.
+ jump (int, optional): Number of positions to jump between adjacent pairs of wires. Defaults to 1.
+ circular (bool, optional): Flag indicating if the pattern should be circular. Defaults to False.
"""
+
"""pattern:
circular = False
jump = 1: [0, 1], [1, 2], [2, 3], [3, 4], [4, 5]
@@ -677,20 +694,21 @@ def forward(self, q_device):
class Op2QFit32Layer(tq.QuantumModule):
"""
- Quantum layer applying the same two-qubit operation to all pairs of adjacent wires, fitting to 32 operations.
+ Quantum layer applying the same two-qubit operation to all pairs of adjacent wires, fitting to 32 operations.
- This class represents a quantum layer that applies the same two-qubit operation to all pairs of adjacent wires in the quantum device. The pairs of wires can be determined in a circular or non-circular pattern based on the specified jump. The layer is designed to fit to 32 operations by repeating the same operation pattern multiple times.
+ This class represents a quantum layer that applies the same two-qubit operation to all pairs of adjacent wires in the quantum device. The pairs of wires can be determined in a circular or non-circular pattern based on the specified jump. The layer is designed to fit to 32 operations by repeating the same operation pattern multiple times.
- Args:
- op (tq.Operator): Two-qubit operation to be applied.
- n_wires (int): Number of wires in the quantum device.
- has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
- trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
- wire_reverse (bool, optional): Flag indicating if the order of wires in each pair should be reversed. Defaults to False.
- jump (int, optional): Number of positions to jump between adjacent pairs of wires. Defaults to 1.
- circular (bool, optional): Flag indicating if the pattern should be circular. Defaults to False.
+ Args:
+ op (tq.Operator): Two-qubit operation to be applied.
+ n_wires (int): Number of wires in the quantum device.
+ has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
+ trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
+ wire_reverse (bool, optional): Flag indicating if the order of wires in each pair should be reversed. Defaults to False.
+ jump (int, optional): Number of positions to jump between adjacent pairs of wires. Defaults to 1.
+ circular (bool, optional): Flag indicating if the pattern should be circular. Defaults to False.
+
+ """
- """
def __init__(
self,
op,
@@ -730,18 +748,19 @@ def forward(self, q_device):
class Op2QButterflyLayer(tq.QuantumModule):
"""
- Quantum layer applying the same two-qubit operation in a butterfly pattern.
+ Quantum layer applying the same two-qubit operation in a butterfly pattern.
- This class represents a quantum layer that applies the same two-qubit operation in a butterfly pattern. The butterfly pattern connects the first and last wire, the second and second-to-last wire, and so on, until the center wire(s) in the case of an odd number of wires.
+ This class represents a quantum layer that applies the same two-qubit operation in a butterfly pattern. The butterfly pattern connects the first and last wire, the second and second-to-last wire, and so on, until the center wire(s) in the case of an odd number of wires.
- Args:
- op (tq.Operator): Two-qubit operation to be applied.
- n_wires (int): Number of wires in the quantum device.
- has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
- trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
- wire_reverse (bool, optional): Flag indicating if the order of wires in each pair should be reversed. Defaults to False.
+ Args:
+ op (tq.Operator): Two-qubit operation to be applied.
+ n_wires (int): Number of wires in the quantum device.
+ has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
+ trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
+ wire_reverse (bool, optional): Flag indicating if the order of wires in each pair should be reversed. Defaults to False.
+
+ """
- """
"""pattern: [0, 5], [1, 4], [2, 3]"""
def __init__(
@@ -766,20 +785,21 @@ def forward(self, q_device):
self.ops_all[k](q_device, wires=wires)
-class Op2QDenseLayer(tq.QuantumModule):
+class EntangleFull(tq.QuantumModule):
"""
- Quantum layer applying the same two-qubit operation in a dense pattern.
+ Quantum layer applying the same two-qubit operation in a dense pattern.
+
+ This class represents a quantum layer that applies the same two-qubit operation in a dense pattern. The dense pattern connects every pair of wires, ensuring that each wire is connected to every other wire exactly once.
- This class represents a quantum layer that applies the same two-qubit operation in a dense pattern. The dense pattern connects every pair of wires, ensuring that each wire is connected to every other wire exactly once.
+ Args:
+ op (tq.Operator): Two-qubit operation to be applied.
+ n_wires (int): Number of wires in the quantum device.
+ has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
+ trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
+ wire_reverse (bool, optional): Flag indicating if the order of wires in each pair should be reversed. Defaults to False.
- Args:
- op (tq.Operator): Two-qubit operation to be applied.
- n_wires (int): Number of wires in the quantum device.
- has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
- trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
- wire_reverse (bool, optional): Flag indicating if the order of wires in each pair should be reversed. Defaults to False.
+ """
- """
"""pattern:
[0, 1], [0, 2], [0, 3], [0, 4], [0, 5]
[1, 2], [1, 3], [1, 4], [1, 5]
@@ -813,25 +833,30 @@ def forward(self, q_device):
k += 1
+# Adding an alias to the previous name
+Op2QDenseLayer = EntangleFull
+
+
class LayerTemplate0(tq.QuantumModule):
"""
- A template for a custom quantum layer.
+ A template for a custom quantum layer.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer. (Optional)
- n_layers_per_block (int): The number of layers per block. (Optional)
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer. (Optional)
+ n_layers_per_block (int): The number of layers per block. (Optional)
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Methods:
- build_layers: Abstract method to build the layers of the template.
- forward: Applies the quantum layer to the given quantum device.
+ Methods:
+ build_layers: Abstract method to build the layers of the template.
+ forward: Applies the quantum layer to the given quantum device.
+
+ """
- """
def __init__(self, arch: dict = None):
super().__init__()
self.n_wires = arch["n_wires"]
@@ -854,25 +879,24 @@ def forward(self, q_device: tq.QuantumDevice):
class U3CU3Layer0(LayerTemplate0):
"""
- Layer template with U3 and CU3 blocks.
+ Layer template with U3 and CU3 blocks.
- This layer template consists of U3 and CU3 blocks repeated for the specified number of blocks.
+ This layer template consists of U3 and CU3 blocks repeated for the specified number of blocks.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
-
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Methods:
- build_layers: Builds the U3 and CU3 layers for the template.
- forward: Applies the quantum layer to the given quantum device.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- """
+ Methods:
+ build_layers: Builds the U3 and CU3 layers for the template.
+ forward: Applies the quantum layer to the given quantum device.
+ """
def build_layers(self):
layers_all = tq.QuantumModuleList()
@@ -897,25 +921,24 @@ def build_layers(self):
class CU3Layer0(LayerTemplate0):
"""
- Layer template with CU3 blocks.
-
- This layer template consists of CU3 blocks repeated for the specified number of blocks.
+ Layer template with CU3 blocks.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ This layer template consists of CU3 blocks repeated for the specified number of blocks.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Methods:
- build_layers: Builds the CU3 layers for the template.
- forward: Applies the quantum layer to the given quantum device.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- """
+ Methods:
+ build_layers: Builds the CU3 layers for the template.
+ forward: Applies the quantum layer to the given quantum device.
+ """
def build_layers(self):
layers_all = tq.QuantumModuleList()
@@ -935,25 +958,24 @@ def build_layers(self):
class CXRZSXLayer0(LayerTemplate0):
"""
- Layer template with CXRZSX blocks.
+ Layer template with CXRZSX blocks.
- This layer template consists of CXRZSX blocks, which include RZ, CNOT, and SX gates, repeated for the specified number of blocks.
+ This layer template consists of CXRZSX blocks, which include RZ, CNOT, and SX gates, repeated for the specified number of blocks.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Methods:
- build_layers: Builds the CXRZSX layers for the template.
- forward: Applies the quantum layer to the given quantum device.
-
- """
+ Methods:
+ build_layers: Builds the CXRZSX layers for the template.
+ forward: Applies the quantum layer to the given quantum device.
+ """
def build_layers(self):
layers_all = tq.QuantumModuleList()
@@ -987,24 +1009,25 @@ def build_layers(self):
class SethLayer0(LayerTemplate0):
"""
- Layer template with Seth blocks.
+ Layer template with Seth blocks.
- This layer template consists of Seth blocks, which include RZZ and RY gates, repeated for the specified number of blocks.
+ This layer template consists of Seth blocks, which include RZZ and RY gates, repeated for the specified number of blocks.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Methods:
- build_layers: Builds the Seth layers for the template.
- forward: Applies the quantum layer to the given quantum device.
+ Methods:
+ build_layers: Builds the Seth layers for the template.
+ forward: Applies the quantum layer to the given quantum device.
+
+ """
- """
def build_layers(self):
layers_all = tq.QuantumModuleList()
for k in range(self.arch["n_blocks"]):
@@ -1028,24 +1051,25 @@ def build_layers(self):
class SethLayer1(LayerTemplate0):
"""
- Layer template with extended Seth blocks.
+ Layer template with extended Seth blocks.
+
+ This layer template consists of extended Seth blocks, which include RZZ and RY gates repeated twice for each block.
- This layer template consists of extended Seth blocks, which include RZZ and RY gates repeated twice for each block.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Methods:
+ build_layers: Builds the extended Seth layers for the template.
+ forward: Applies the quantum layer to the given quantum device.
- Methods:
- build_layers: Builds the extended Seth layers for the template.
- forward: Applies the quantum layer to the given quantum device.
+ """
- """
def build_layers(self):
layers_all = tq.QuantumModuleList()
for k in range(self.arch["n_blocks"]):
@@ -1079,24 +1103,25 @@ def build_layers(self):
class SethLayer2(LayerTemplate0):
"""
- Layer template with Seth blocks using Op2QFit32Layer.
+ Layer template with Seth blocks using Op2QFit32Layer.
- This layer template consists of Seth blocks using the Op2QFit32Layer, which includes RZZ gates and supports 32 wires.
+ This layer template consists of Seth blocks using the Op2QFit32Layer, which includes RZZ gates and supports 32 wires.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Methods:
- build_layers: Builds the Seth layers with Op2QFit32Layer for the template.
- forward: Applies the quantum layer to the given quantum device.
+ Methods:
+ build_layers: Builds the Seth layers with Op2QFit32Layer for the template.
+ forward: Applies the quantum layer to the given quantum device.
+
+ """
- """
def build_layers(self):
layers_all = tq.QuantumModuleList()
for k in range(self.arch["n_blocks"]):
@@ -1115,24 +1140,25 @@ def build_layers(self):
class RZZLayer0(LayerTemplate0):
"""
- Layer template with RZZ blocks.
+ Layer template with RZZ blocks.
- This layer template consists of RZZ blocks using the Op2QAllLayer.
+ This layer template consists of RZZ blocks using the Op2QAllLayer.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Methods:
- build_layers: Builds the RZZ layers with Op2QAllLayer for the template.
- forward: Applies the quantum layer to the given quantum device.
+ Methods:
+ build_layers: Builds the RZZ layers with Op2QAllLayer for the template.
+ forward: Applies the quantum layer to the given quantum device.
+
+ """
- """
def build_layers(self):
layers_all = tq.QuantumModuleList()
for k in range(self.arch["n_blocks"]):
@@ -1151,24 +1177,25 @@ def build_layers(self):
class BarrenLayer0(LayerTemplate0):
"""
- Layer template with Barren blocks.
+ Layer template with Barren blocks.
- This layer template consists of Barren blocks using the Op1QAllLayer and Op2QAllLayer.
+ This layer template consists of Barren blocks using the Op1QAllLayer and Op2QAllLayer.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Methods:
- build_layers: Builds the Barren layers with Op1QAllLayer and Op2QAllLayer for the template.
- forward: Applies the quantum layer to the given quantum device.
+ Methods:
+ build_layers: Builds the Barren layers with Op1QAllLayer and Op2QAllLayer for the template.
+ forward: Applies the quantum layer to the given quantum device.
+
+ """
- """
def build_layers(self):
layers_all = tq.QuantumModuleList()
layers_all.append(
@@ -1199,24 +1226,25 @@ def build_layers(self):
class FarhiLayer0(LayerTemplate0):
"""
- Layer template with Farhi blocks.
+ Layer template with Farhi blocks.
- This layer template consists of Farhi blocks using the Op2QAllLayer.
+ This layer template consists of Farhi blocks using the Op2QAllLayer.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Methods:
- build_layers: Builds the Farhi layers with Op2QAllLayer for the template.
- forward: Applies the quantum layer to the given quantum device.
+ Methods:
+ build_layers: Builds the Farhi layers with Op2QAllLayer for the template.
+ forward: Applies the quantum layer to the given quantum device.
+
+ """
- """
def build_layers(self):
layers_all = tq.QuantumModuleList()
for k in range(self.arch["n_blocks"]):
@@ -1245,24 +1273,25 @@ def build_layers(self):
class MaxwellLayer0(LayerTemplate0):
"""
- Layer template with Maxwell blocks.
+ Layer template with Maxwell blocks.
+
+ This layer template consists of Maxwell blocks using the Op1QAllLayer and Op2QAllLayer modules.
- This layer template consists of Maxwell blocks using the Op1QAllLayer and Op2QAllLayer modules.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Methods:
+ build_layers: Builds the Maxwell layers with Op1QAllLayer and Op2QAllLayer for the template.
+ forward: Applies the quantum layer to the given quantum device.
- Methods:
- build_layers: Builds the Maxwell layers with Op1QAllLayer and Op2QAllLayer for the template.
- forward: Applies the quantum layer to the given quantum device.
+ """
- """
def build_layers(self):
layers_all = tq.QuantumModuleList()
for k in range(self.arch["n_blocks"]):
@@ -1317,24 +1346,25 @@ def build_layers(self):
class RYRYCXLayer0(LayerTemplate0):
"""
- Layer template with RYRYCX blocks.
+ Layer template with RYRYCX blocks.
+
+ This layer template consists of RYRYCX blocks using the Op1QAllLayer and CXLayer modules.
- This layer template consists of RYRYCX blocks using the Op1QAllLayer and CXLayer modules.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Methods:
+ build_layers: Builds the RYRYCX layers with Op1QAllLayer and CXLayer for the template.
+ forward: Applies the quantum layer to the given quantum device.
- Methods:
- build_layers: Builds the RYRYCX layers with Op1QAllLayer and CXLayer for the template.
- forward: Applies the quantum layer to the given quantum device.
+ """
- """
def build_layers(self):
layers_all = tq.QuantumModuleList()
for k in range(self.arch["n_blocks"]):
@@ -1349,23 +1379,23 @@ def build_layers(self):
class RYRYRYCXCXCXLayer0(LayerTemplate0):
"""
- Layer template with RYRYRYCXCXCX blocks.
+ Layer template with RYRYRYCXCXCX blocks.
- This layer template consists of RYRYRYCXCXCX blocks using the RYRYCXCXLayer module.
+ This layer template consists of RYRYRYCXCXCX blocks using the RYRYCXCXLayer module.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Methods:
- build_layers: Builds the RYRYRYCXCXCX layers with RYRYCXCXLayer for the template.
+ Methods:
+ build_layers: Builds the RYRYRYCXCXCX layers with RYRYCXCXLayer for the template.
- """
+ """
def build_layers(self):
layers_all = tq.QuantumModuleList()
@@ -1381,24 +1411,25 @@ def build_layers(self):
class RYRYRYLayer0(LayerTemplate0):
"""
- Layer template with RYRYRYCXCXCX blocks.
+ Layer template with RYRYRYCXCXCX blocks.
- This layer template consists of RYRYRYCXCXCX blocks using the Op1QAllLayer and CXCXCXLayer modules.
+ This layer template consists of RYRYRYCXCXCX blocks using the Op1QAllLayer and CXCXCXLayer modules.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Methods:
- build_layers: Builds the RYRYRYCXCXCX layers with Op1QAllLayer and CXCXCXLayer for the template.
+ Methods:
+ build_layers: Builds the RYRYRYCXCXCX layers with Op1QAllLayer and CXCXCXLayer for the template.
- """
+ """
+
def build_layers(self):
layers_all = tq.QuantumModuleList()
for k in range(self.arch["n_blocks"]):
@@ -1412,24 +1443,25 @@ def build_layers(self):
class RYRYRYSWAPSWAPLayer0(LayerTemplate0):
"""
- Layer template with RYRYRYSWAPSWAP blocks.
+ Layer template with RYRYRYSWAPSWAP blocks.
- This layer template consists of RYRYRYSWAPSWAP blocks using the Op1QAllLayer and SWAPSWAPLayer modules.
+ This layer template consists of RYRYRYSWAPSWAP blocks using the Op1QAllLayer and SWAPSWAPLayer modules.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Methods:
- build_layers: Builds the RYRYRYSWAPSWAP layers with Op1QAllLayer and SWAPSWAPLayer for the template.
+ Methods:
+ build_layers: Builds the RYRYRYSWAPSWAP layers with Op1QAllLayer and SWAPSWAPLayer for the template.
- """
+ """
+
def build_layers(self):
layers_all = tq.QuantumModuleList()
for k in range(self.arch["n_blocks"]):
@@ -1444,23 +1476,23 @@ def build_layers(self):
class SWAPSWAPLayer0(LayerTemplate0):
"""
- Layer template with SWAPSWAP blocks.
+ Layer template with SWAPSWAP blocks.
- This layer template consists of SWAPSWAP blocks using the SWAPSWAPLayer module.
+ This layer template consists of SWAPSWAP blocks using the SWAPSWAPLayer module.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Methods:
- build_layers: Builds the SWAPSWAP layers with SWAPSWAPLayer for the template.
+ Methods:
+ build_layers: Builds the SWAPSWAP layers with SWAPSWAPLayer for the template.
- """
+ """
def build_layers(self):
layers_all = tq.QuantumModuleList()
@@ -1471,23 +1503,24 @@ def build_layers(self):
class RXYZCXLayer0(LayerTemplate0):
"""
- Layer template with RXYZCX blocks.
+ Layer template with RXYZCX blocks.
- This layer template consists of RXYZCX blocks using the RXYZCXLayer module.
+ This layer template consists of RXYZCX blocks using the RXYZCXLayer module.
- Args:
- arch (dict, optional): The architecture configuration for the layer. Defaults to None.
+ Args:
+ arch (dict, optional): The architecture configuration for the layer. Defaults to None.
- Attributes:
- n_wires (int): The number of wires in the layer.
- arch (dict): The architecture configuration for the layer.
- n_blocks (int): The number of blocks in the layer.
- layers_all (tq.QuantumModuleList): The list of layers in the template.
+ Attributes:
+ n_wires (int): The number of wires in the layer.
+ arch (dict): The architecture configuration for the layer.
+ n_blocks (int): The number of blocks in the layer.
+ layers_all (tq.QuantumModuleList): The list of layers in the template.
- Methods:
- build_layers: Builds the RXYZCX layers with RXYZCXLayer for the template.
+ Methods:
+ build_layers: Builds the RXYZCX layers with RXYZCXLayer for the template.
+
+ """
- """
def build_layers(self):
layers_all = tq.QuantumModuleList()
for k in range(self.arch["n_blocks"]):
@@ -1619,6 +1652,190 @@ def forward(self, q_device: tq.QuantumDevice):
self.gates_all(q_device)
+class EntangleLinear(Op2QAllLayer):
+ """
+ Quantum layer applying the same two-qubit operation to all pairs of adjacent wires.
+ This class represents a quantum layer that applies the same two-qubit operation to all pairs of adjacent wires
+ in the quantum device.
+
+ Args:
+ op (tq.Operator): Two-qubit operation to be applied.
+ n_wires (int): Number of wires in the quantum device.
+ has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
+ trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
+ wire_reverse (bool, optional): Flag indicating if the order of wires in each pair should be reversed. Defaults to False.
+ """
+
+ """pattern: [0, 1], [1, 2], [2, 3], [3, 4], [4, 5]
+ """
+
+ def __init__(
+ self,
+ op,
+ n_wires: int,
+ has_params=False,
+ trainable=False,
+ wire_reverse=False,
+ ):
+ super().__init__(
+ op=op,
+ n_wires=n_wires,
+ has_params=has_params,
+ trainable=trainable,
+ wire_reverse=wire_reverse,
+ jump=1,
+ circular=False,
+ )
+
+
+class EntangleCircular(Op2QAllLayer):
+ """
+ Quantum layer applying the same two-qubit operation to all pairs of adjacent wires in a circular manner.
+ This class represents a quantum layer that applies the same two-qubit operation to all pairs of adjacent wires
+ in the quantum device with a wrap-around
+
+ Args:
+ op (tq.Operator): Two-qubit operation to be applied.
+ n_wires (int): Number of wires in the quantum device.
+ has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
+ trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
+ wire_reverse (bool, optional): Flag indicating if the order of wires in each pair should be reversed. Defaults to False.
+ jump (int, optional): Number of positions to jump between adjacent pairs of wires. Defaults to 1.
+ circular (bool, optional): Flag indicating if the pattern should be circular. Defaults to False.
+
+ """
+
+ """pattern: [0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 0]
+ """
+
+ def __init__(
+ self,
+ op,
+ n_wires: int,
+ has_params=False,
+ trainable=False,
+ wire_reverse=False,
+ ):
+ super().__init__(
+ op=op,
+ n_wires=n_wires,
+ has_params=has_params,
+ trainable=trainable,
+ wire_reverse=wire_reverse,
+ jump=1,
+ circular=True,
+ )
+
+
+class EntanglePairwise(tq.QuantumModule):
+ """
+ Quantum layer applying the same two-qubit operation in a pair-wise pattern
+
+ This class represents a quantum layer that applies the same two-qubit operation in a pairwise pattern. The pairwise pattern first entangles all qubits i with i+1 for even i then all qubits i with i+1 for odd i.
+
+ Args:
+ op (tq.Operator): Two-qubit operation to be applied.
+ n_wires (int): Number of wires in the quantum device.
+ has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
+ trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
+ wire_reverse (bool, optional): Flag indicating if the order of wires in each pair should be reversed. Defaults to False.
+
+ """
+
+ """pattern:
+ [0, 1], [2, 3], [4, 5]
+ [1, 2], [3, 4]
+ """
+
+ def __init__(
+ self, op, n_wires: int, has_params=False, trainable=False, wire_reverse=False
+ ):
+ super().__init__()
+ self.n_wires = n_wires
+ self.op = op
+ self.ops_all = tq.QuantumModuleList()
+
+ # reverse the wires, for example from [1, 2] to [2, 1]
+ self.wire_reverse = wire_reverse
+
+ for k in range(self.n_wires - 1):
+ self.ops_all.append(op(has_params=has_params, trainable=trainable))
+
+ def forward(self, q_device):
+ k = 0
+
+ # entangle qubit i with i+1 for all even values of i
+ for i in range(self.n_wires - 1):
+ if i % 2 == 0:
+ wires = [i, i + 1]
+ if self.wire_reverse:
+ wires.reverse()
+ self.ops_all[k](q_device, wires=wires)
+ k += 1
+
+ # entangle qubit i with i+1 for all odd values of i
+ for i in range(1, self.n_wires - 1):
+ if i % 2 == 1:
+ wires = [i, i + 1]
+ if self.wire_reverse:
+ wires.reverse()
+ self.ops_all[k](q_device, wires=wires)
+ k += 1
+
+
+class EntanglementLayer(tq.QuantumModule):
+ """
+ Quantum layer applying a specified two-qubit entanglement type to all qubits. The entanglement types include full, linear, pairwise, and circular.
+
+ Args:
+ op (tq.Operator): Two-qubit operation to be applied.
+ n_wires (int): Number of wires in the quantum device.
+ entanglement (str): Type of entanglement from ["full", "linear", "pairwise", "circular"]
+ has_params (bool, optional): Flag indicating if the operation has parameters. Defaults to False.
+ trainable (bool, optional): Flag indicating if the operation is trainable. Defaults to False.
+ wire_reverse (bool, optional): Flag indicating if the order of wires in each pair should be reversed. Defaults to False.
+ jump (int, optional): Number of positions to jump between adjacent pairs of wires. Defaults to 1.
+ circular (bool, optional): Flag indicating if the pattern should be circular. Defaults to False.
+
+ """
+
+ def __init__(
+ self,
+ op,
+ n_wires: int,
+ entanglement: str,
+ has_params=False,
+ trainable=False,
+ wire_reverse=False,
+ ):
+ super().__init__()
+
+ entanglement_to_class = {
+ "full": EntangleFull,
+ "linear": EntangleLinear,
+ "pairwise": EntanglePairwise,
+ "circular": EntangleCircular,
+ }
+
+ self.entanglement_class = entanglement_to_class.get(entanglement, None)
+
+ assert (
+ self.entanglement_class is not None
+ ), f"invalid entanglement type {entanglement}"
+
+ self.entanglement_class.__init__(
+ op=op,
+ n_wires=n_wires,
+ has_params=has_params,
+ trainable=trainable,
+ wire_reverse=wire_reverse,
+ )
+
+ @tq.static_support
+ def forward(self, q_device):
+ self.entanglement_class.forward(q_device)
+
+
layer_name_dict = {
"u3cu3_0": U3CU3Layer0,
"cu3_0": CU3Layer0,
diff --git a/torchquantum/plugin/qiskit/qiskit_plugin.py b/torchquantum/plugin/qiskit/qiskit_plugin.py
index 9dca0649..bca3a7d2 100644
--- a/torchquantum/plugin/qiskit/qiskit_plugin.py
+++ b/torchquantum/plugin/qiskit/qiskit_plugin.py
@@ -682,7 +682,10 @@ def qiskit2tq_Operator(circ: QuantumCircuit):
try:
p2v_orig = circ._layout.final_layout.get_physical_bits().copy()
except:
- p2v_orig = circ._layout.get_physical_bits().copy()
+ try:
+ p2v_orig = circ._layout.get_physical_bits().copy()
+ except:
+ p2v_orig = circ._layout.initial_layout.get_physical_bits().copy()
p2v = {}
for p, v in p2v_orig.items():
if v.register.name == "q":
diff --git a/torchquantum/plugin/qiskit/qiskit_unitary_gate.py b/torchquantum/plugin/qiskit/qiskit_unitary_gate.py
index d2b93577..6e520b96 100644
--- a/torchquantum/plugin/qiskit/qiskit_unitary_gate.py
+++ b/torchquantum/plugin/qiskit/qiskit_unitary_gate.py
@@ -23,7 +23,6 @@
from qiskit.circuit.exceptions import CircuitError
from qiskit.circuit._utils import _compute_control_matrix
from qiskit.circuit.library.standard_gates import U3Gate
-from qiskit.extensions.quantum_initializer import isometry
from qiskit.quantum_info.operators.predicates import matrix_equal
from qiskit.quantum_info.operators.predicates import is_unitary_matrix
from qiskit.quantum_info.synthesis.one_qubit_decompose import OneQubitEulerDecomposer
@@ -117,7 +116,7 @@ def _define(self):
else:
q = QuantumRegister(self.num_qubits, "q")
qc = QuantumCircuit(q, name=self.name)
- qc.append(isometry.Isometry(self.to_matrix(), 0, 0), qargs=q[:])
+ qc.append(qiskit.circuit.library.Isometry(self.to_matrix(), 0, 0), qargs=q[:])
self.definition = qc
def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None):
@@ -139,7 +138,7 @@ def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None):
cmat = _compute_control_matrix(
self.to_matrix(), num_ctrl_qubits, ctrl_state=None
)
- iso = isometry.Isometry(cmat, 0, 0)
+ iso = qiskit.circuit.library.Isometry(cmat, 0, 0)
cunitary = ControlledGate(
"c-unitary",
num_qubits=self.num_qubits + num_ctrl_qubits,
diff --git a/torchquantum/pulse/utils.py b/torchquantum/pulse/utils.py
index e80465c2..eb0c7b82 100644
--- a/torchquantum/pulse/utils.py
+++ b/torchquantum/pulse/utils.py
@@ -40,7 +40,7 @@ def InitialState(n_qubit = 1, state = [0]):
def InitialDensity(n_qubit = 1, state = [0]):
initial_state = InitialState(n_qubit, state)
- initial_density = torch.ger(initial_state, torch.conj(initial_state))
+ initial_density = torch.outer(initial_state, torch.conj(initial_state))
return initial_density
def H_2q_example(pulse, dt):