hqm.circuits.customcircuits
Work in progress
1''' 2 Work in progress 3''' 4from types import FunctionType 5import pennylane as qml 6import numpy as np 7import sys 8 9sys.path += ['.', './utils/'] 10 11from .circuit import QuantumCircuit 12 13class BellmanCircuit(QuantumCircuit): 14 ''' 15 This class implements a torch/keras quantum layer using the bellman 16 circuit. 17 ''' 18 19 def __init__(self, n_qubits : int, n_layers : int, dev : qml.devices = None, encoding : str = 'angle') -> None: 20 ''' 21 BellmanCircuit constructor. 22 23 Parameters: 24 ----------- 25 - n_qubits : int 26 number of qubits for the quantum circuit 27 - n_layers : int 28 number of layers for the quantum circuit 29 - dev : qml.device 30 PennyLane device on wich run quantum operations (dafault : None). When None it will be set 31 to 'default.qubit' 32 - encoding : str 33 string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude' 34 35 Returns: 36 -------- 37 Nothing, a BellmanCircuit object will be created. 38 ''' 39 40 super().__init__(n_qubits=n_qubits, n_layers=n_layers, dev=dev) 41 42 if encoding not in ['angle', 'amplitude']: raise(f"encoding can be angle or amplitude, found {encoding}") 43 44 self.encoding = encoding 45 self.weight_shape = {"weights": (n_layers, n_qubits, 3)} 46 self.circuit = self.circ(self.dev, self.n_qubits, self.n_layers, self.encoding) 47 48 @staticmethod 49 def circ(dev : qml.devices, n_qubits : int, n_layers : int, encoding : str) -> FunctionType: 50 ''' 51 BellmanCircuit static method that implements the quantum circuit. 52 53 Parameters: 54 ----------- 55 - dev : qml.device 56 PennyLane device on wich run quantum operations (dafault : None). When None it will be set 57 to 'default.qubit' 58 - n_qubits : int 59 number of qubits for the quantum circuit 60 - n_layers : int 61 number of layers for the quantum circuit 62 - encoding : str 63 string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude' 64 65 Returns: 66 -------- 67 - qnode : qml.qnode 68 the actual PennyLane circuit 69 ''' 70 @qml.qnode(dev) 71 def qnode(inputs : np.ndarray, weights : np.ndarray) -> list: 72 ''' 73 PennyLane based quantum circuit composed of an angle embedding layer and a basic entangler 74 layer. 75 76 Parameters: 77 ----------- 78 - inputs : np.ndarray 79 array containing input values (can came from previous torch/keras layers or quantum layers) 80 - weights : np.ndarray 81 array containing the weights of the circuit that are tuned during training, the shape of this 82 array depends on circuit's layers and qubits. 83 84 Returns: 85 -------- 86 - measurements : list 87 list of values measured from the quantum circuits 88 ''' 89 90 if encoding == 'angle': qml.AngleEmbedding(inputs, wires=range(n_qubits)) 91 if encoding == 'amplitude': qml.AmplitudeEmbedding(features=inputs, wires=range(n_qubits), normalize=True) 92 93 for n in range(n_layers): 94 qml.Hadamard(wires=0) 95 96 # CNOT gates 97 for q in range(1, n_qubits): 98 qml.CNOT(wires=[q-1, q]) 99 100 # Rot gates in the middle 101 for q in range(n_qubits): 102 qml.Rot(weights[n, q, 0], weights[n, q, 1], weights[n, q, 2], wires=q) 103 104 # CNOT gates 105 for q in range(1, n_qubits): 106 qml.CNOT(wires=[n_qubits - q-1, n_qubits - q]) 107 108 measurements = [qml.expval(qml.PauliZ(wires=i)) for i in range(n_qubits)] 109 return measurements 110 111 return qnode 112 113class RealAmplitudesCircuit(QuantumCircuit): 114 ''' 115 This class implements a torch/keras quantum layer using the real amplitude circuit. 116 ''' 117 118 def __init__(self, n_qubits : int, n_layers : int, dev : qml.devices = None, encoding : str = 'angle') -> None: 119 ''' 120 RealAmplitudesCircuit constructor. 121 122 Parameters: 123 ----------- 124 - n_qubits : int 125 number of qubits for the quantum circuit 126 - n_layers : int 127 number of layers for the quantum circuit 128 - dev : qml.device 129 PennyLane device on wich run quantum operations (dafault : None). When None it will be set 130 to 'default.qubit' 131 - encoding : str 132 string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude' 133 134 Returns: 135 -------- 136 Nothing, a RealAmplitudesCircuit object will be created. 137 ''' 138 super().__init__(n_qubits=n_qubits, n_layers=n_layers, dev=dev) 139 140 if encoding not in ['angle', 'amplitude']: raise(f"encoding can be angle or amplitude, found {encoding}") 141 142 self.encoding = encoding 143 self.weight_shape = {"weights": (n_layers, n_qubits, 3)} 144 self.circuit = self.circ(self.dev, self.n_qubits, self.n_layers, self.encoding) 145 146 @staticmethod 147 def circ(dev : qml.devices, n_qubits : int, n_layers : int, encoding : str) -> FunctionType: 148 ''' 149 RealAmplitudesCircuit static method that implements the quantum circuit. 150 151 Parameters: 152 ----------- 153 - dev : qml.device 154 PennyLane device on wich run quantum operations (dafault : None). When None it will be set 155 to 'default.qubit' 156 - n_qubits : int 157 number of qubits for the quantum circuit 158 - n_layers : int 159 number of layers for the quantum circuit 160 - encoding : str 161 string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude' 162 163 Returns: 164 -------- 165 - qnode : qml.qnode 166 the actual PennyLane circuit 167 ''' 168 @qml.qnode(dev) 169 def qnode(inputs : np.ndarray, weights : np.ndarray) -> list: 170 ''' 171 PennyLane based quantum circuit composed of an angle embedding layer and a basic entangler 172 layer. 173 174 Parameters: 175 ----------- 176 - inputs : np.ndarray 177 array containing input values (can came from previous torch/keras layers or quantum layers) 178 - weights : np.ndarray 179 array containing the weights of the circuit that are tuned during training, the shape of this 180 array depends on circuit's layers and qubits. 181 182 Returns: 183 -------- 184 - measurements : list 185 list of values measured from the quantum circuits 186 ''' 187 188 if encoding == 'angle': qml.AngleEmbedding(inputs, wires=range(n_qubits)) 189 if encoding == 'amplitude': qml.AmplitudeEmbedding(features=inputs, wires=range(n_qubits), normalize=True) 190 191 for q in range(n_qubits): qml.Hadamard(wires=q) 192 193 for n in range(n_layers): 194 for q1 in range(0, n_qubits): 195 for q2 in range(0, n_qubits): 196 if q1 < q2: 197 qml.CNOT(wires=[q2, q1]) 198 199 # Rot gates in the middle 200 for q in range(n_qubits): 201 qml.Rot(weights[n, q, 0], weights[n, q, 1], weights[n, q, 2], wires=q) 202 203 204 measurements = [qml.expval(qml.PauliZ(wires=i)) for i in range(n_qubits)] 205 return measurements 206 207 return qnode
class
BellmanCircuit(typing.Generic[~quantumcircuit]):
14class BellmanCircuit(QuantumCircuit): 15 ''' 16 This class implements a torch/keras quantum layer using the bellman 17 circuit. 18 ''' 19 20 def __init__(self, n_qubits : int, n_layers : int, dev : qml.devices = None, encoding : str = 'angle') -> None: 21 ''' 22 BellmanCircuit constructor. 23 24 Parameters: 25 ----------- 26 - n_qubits : int 27 number of qubits for the quantum circuit 28 - n_layers : int 29 number of layers for the quantum circuit 30 - dev : qml.device 31 PennyLane device on wich run quantum operations (dafault : None). When None it will be set 32 to 'default.qubit' 33 - encoding : str 34 string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude' 35 36 Returns: 37 -------- 38 Nothing, a BellmanCircuit object will be created. 39 ''' 40 41 super().__init__(n_qubits=n_qubits, n_layers=n_layers, dev=dev) 42 43 if encoding not in ['angle', 'amplitude']: raise(f"encoding can be angle or amplitude, found {encoding}") 44 45 self.encoding = encoding 46 self.weight_shape = {"weights": (n_layers, n_qubits, 3)} 47 self.circuit = self.circ(self.dev, self.n_qubits, self.n_layers, self.encoding) 48 49 @staticmethod 50 def circ(dev : qml.devices, n_qubits : int, n_layers : int, encoding : str) -> FunctionType: 51 ''' 52 BellmanCircuit static method that implements the quantum circuit. 53 54 Parameters: 55 ----------- 56 - dev : qml.device 57 PennyLane device on wich run quantum operations (dafault : None). When None it will be set 58 to 'default.qubit' 59 - n_qubits : int 60 number of qubits for the quantum circuit 61 - n_layers : int 62 number of layers for the quantum circuit 63 - encoding : str 64 string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude' 65 66 Returns: 67 -------- 68 - qnode : qml.qnode 69 the actual PennyLane circuit 70 ''' 71 @qml.qnode(dev) 72 def qnode(inputs : np.ndarray, weights : np.ndarray) -> list: 73 ''' 74 PennyLane based quantum circuit composed of an angle embedding layer and a basic entangler 75 layer. 76 77 Parameters: 78 ----------- 79 - inputs : np.ndarray 80 array containing input values (can came from previous torch/keras layers or quantum layers) 81 - weights : np.ndarray 82 array containing the weights of the circuit that are tuned during training, the shape of this 83 array depends on circuit's layers and qubits. 84 85 Returns: 86 -------- 87 - measurements : list 88 list of values measured from the quantum circuits 89 ''' 90 91 if encoding == 'angle': qml.AngleEmbedding(inputs, wires=range(n_qubits)) 92 if encoding == 'amplitude': qml.AmplitudeEmbedding(features=inputs, wires=range(n_qubits), normalize=True) 93 94 for n in range(n_layers): 95 qml.Hadamard(wires=0) 96 97 # CNOT gates 98 for q in range(1, n_qubits): 99 qml.CNOT(wires=[q-1, q]) 100 101 # Rot gates in the middle 102 for q in range(n_qubits): 103 qml.Rot(weights[n, q, 0], weights[n, q, 1], weights[n, q, 2], wires=q) 104 105 # CNOT gates 106 for q in range(1, n_qubits): 107 qml.CNOT(wires=[n_qubits - q-1, n_qubits - q]) 108 109 measurements = [qml.expval(qml.PauliZ(wires=i)) for i in range(n_qubits)] 110 return measurements 111 112 return qnode
This class implements a torch/keras quantum layer using the bellman circuit.
BellmanCircuit( n_qubits: int, n_layers: int, dev: <module 'pennylane.devices' from '/Users/asebastianelli/miniforge3/envs/hqm/lib/python3.10/site-packages/pennylane/devices/__init__.py'> = None, encoding: str = 'angle')
20 def __init__(self, n_qubits : int, n_layers : int, dev : qml.devices = None, encoding : str = 'angle') -> None: 21 ''' 22 BellmanCircuit constructor. 23 24 Parameters: 25 ----------- 26 - n_qubits : int 27 number of qubits for the quantum circuit 28 - n_layers : int 29 number of layers for the quantum circuit 30 - dev : qml.device 31 PennyLane device on wich run quantum operations (dafault : None). When None it will be set 32 to 'default.qubit' 33 - encoding : str 34 string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude' 35 36 Returns: 37 -------- 38 Nothing, a BellmanCircuit object will be created. 39 ''' 40 41 super().__init__(n_qubits=n_qubits, n_layers=n_layers, dev=dev) 42 43 if encoding not in ['angle', 'amplitude']: raise(f"encoding can be angle or amplitude, found {encoding}") 44 45 self.encoding = encoding 46 self.weight_shape = {"weights": (n_layers, n_qubits, 3)} 47 self.circuit = self.circ(self.dev, self.n_qubits, self.n_layers, self.encoding)
BellmanCircuit constructor.
Parameters:
- n_qubits : int
number of qubits for the quantum circuit - n_layers : int
number of layers for the quantum circuit - dev : qml.device
PennyLane device on wich run quantum operations (dafault : None). When None it will be set to 'default.qubit' - encoding : str
string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude'
Returns:
Nothing, a BellmanCircuit object will be created.
@staticmethod
def
circ( dev: <module 'pennylane.devices' from '/Users/asebastianelli/miniforge3/envs/hqm/lib/python3.10/site-packages/pennylane/devices/__init__.py'>, n_qubits: int, n_layers: int, encoding: str) -> function:
49 @staticmethod 50 def circ(dev : qml.devices, n_qubits : int, n_layers : int, encoding : str) -> FunctionType: 51 ''' 52 BellmanCircuit static method that implements the quantum circuit. 53 54 Parameters: 55 ----------- 56 - dev : qml.device 57 PennyLane device on wich run quantum operations (dafault : None). When None it will be set 58 to 'default.qubit' 59 - n_qubits : int 60 number of qubits for the quantum circuit 61 - n_layers : int 62 number of layers for the quantum circuit 63 - encoding : str 64 string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude' 65 66 Returns: 67 -------- 68 - qnode : qml.qnode 69 the actual PennyLane circuit 70 ''' 71 @qml.qnode(dev) 72 def qnode(inputs : np.ndarray, weights : np.ndarray) -> list: 73 ''' 74 PennyLane based quantum circuit composed of an angle embedding layer and a basic entangler 75 layer. 76 77 Parameters: 78 ----------- 79 - inputs : np.ndarray 80 array containing input values (can came from previous torch/keras layers or quantum layers) 81 - weights : np.ndarray 82 array containing the weights of the circuit that are tuned during training, the shape of this 83 array depends on circuit's layers and qubits. 84 85 Returns: 86 -------- 87 - measurements : list 88 list of values measured from the quantum circuits 89 ''' 90 91 if encoding == 'angle': qml.AngleEmbedding(inputs, wires=range(n_qubits)) 92 if encoding == 'amplitude': qml.AmplitudeEmbedding(features=inputs, wires=range(n_qubits), normalize=True) 93 94 for n in range(n_layers): 95 qml.Hadamard(wires=0) 96 97 # CNOT gates 98 for q in range(1, n_qubits): 99 qml.CNOT(wires=[q-1, q]) 100 101 # Rot gates in the middle 102 for q in range(n_qubits): 103 qml.Rot(weights[n, q, 0], weights[n, q, 1], weights[n, q, 2], wires=q) 104 105 # CNOT gates 106 for q in range(1, n_qubits): 107 qml.CNOT(wires=[n_qubits - q-1, n_qubits - q]) 108 109 measurements = [qml.expval(qml.PauliZ(wires=i)) for i in range(n_qubits)] 110 return measurements 111 112 return qnode
BellmanCircuit static method that implements the quantum circuit.
Parameters:
- dev : qml.device
PennyLane device on wich run quantum operations (dafault : None). When None it will be set
to 'default.qubit' - n_qubits : int
number of qubits for the quantum circuit - n_layers : int
number of layers for the quantum circuit - encoding : str
string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude'
Returns:
- qnode : qml.qnode
the actual PennyLane circuit
class
RealAmplitudesCircuit(typing.Generic[~quantumcircuit]):
114class RealAmplitudesCircuit(QuantumCircuit): 115 ''' 116 This class implements a torch/keras quantum layer using the real amplitude circuit. 117 ''' 118 119 def __init__(self, n_qubits : int, n_layers : int, dev : qml.devices = None, encoding : str = 'angle') -> None: 120 ''' 121 RealAmplitudesCircuit constructor. 122 123 Parameters: 124 ----------- 125 - n_qubits : int 126 number of qubits for the quantum circuit 127 - n_layers : int 128 number of layers for the quantum circuit 129 - dev : qml.device 130 PennyLane device on wich run quantum operations (dafault : None). When None it will be set 131 to 'default.qubit' 132 - encoding : str 133 string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude' 134 135 Returns: 136 -------- 137 Nothing, a RealAmplitudesCircuit object will be created. 138 ''' 139 super().__init__(n_qubits=n_qubits, n_layers=n_layers, dev=dev) 140 141 if encoding not in ['angle', 'amplitude']: raise(f"encoding can be angle or amplitude, found {encoding}") 142 143 self.encoding = encoding 144 self.weight_shape = {"weights": (n_layers, n_qubits, 3)} 145 self.circuit = self.circ(self.dev, self.n_qubits, self.n_layers, self.encoding) 146 147 @staticmethod 148 def circ(dev : qml.devices, n_qubits : int, n_layers : int, encoding : str) -> FunctionType: 149 ''' 150 RealAmplitudesCircuit static method that implements the quantum circuit. 151 152 Parameters: 153 ----------- 154 - dev : qml.device 155 PennyLane device on wich run quantum operations (dafault : None). When None it will be set 156 to 'default.qubit' 157 - n_qubits : int 158 number of qubits for the quantum circuit 159 - n_layers : int 160 number of layers for the quantum circuit 161 - encoding : str 162 string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude' 163 164 Returns: 165 -------- 166 - qnode : qml.qnode 167 the actual PennyLane circuit 168 ''' 169 @qml.qnode(dev) 170 def qnode(inputs : np.ndarray, weights : np.ndarray) -> list: 171 ''' 172 PennyLane based quantum circuit composed of an angle embedding layer and a basic entangler 173 layer. 174 175 Parameters: 176 ----------- 177 - inputs : np.ndarray 178 array containing input values (can came from previous torch/keras layers or quantum layers) 179 - weights : np.ndarray 180 array containing the weights of the circuit that are tuned during training, the shape of this 181 array depends on circuit's layers and qubits. 182 183 Returns: 184 -------- 185 - measurements : list 186 list of values measured from the quantum circuits 187 ''' 188 189 if encoding == 'angle': qml.AngleEmbedding(inputs, wires=range(n_qubits)) 190 if encoding == 'amplitude': qml.AmplitudeEmbedding(features=inputs, wires=range(n_qubits), normalize=True) 191 192 for q in range(n_qubits): qml.Hadamard(wires=q) 193 194 for n in range(n_layers): 195 for q1 in range(0, n_qubits): 196 for q2 in range(0, n_qubits): 197 if q1 < q2: 198 qml.CNOT(wires=[q2, q1]) 199 200 # Rot gates in the middle 201 for q in range(n_qubits): 202 qml.Rot(weights[n, q, 0], weights[n, q, 1], weights[n, q, 2], wires=q) 203 204 205 measurements = [qml.expval(qml.PauliZ(wires=i)) for i in range(n_qubits)] 206 return measurements 207 208 return qnode
This class implements a torch/keras quantum layer using the real amplitude circuit.
RealAmplitudesCircuit( n_qubits: int, n_layers: int, dev: <module 'pennylane.devices' from '/Users/asebastianelli/miniforge3/envs/hqm/lib/python3.10/site-packages/pennylane/devices/__init__.py'> = None, encoding: str = 'angle')
119 def __init__(self, n_qubits : int, n_layers : int, dev : qml.devices = None, encoding : str = 'angle') -> None: 120 ''' 121 RealAmplitudesCircuit constructor. 122 123 Parameters: 124 ----------- 125 - n_qubits : int 126 number of qubits for the quantum circuit 127 - n_layers : int 128 number of layers for the quantum circuit 129 - dev : qml.device 130 PennyLane device on wich run quantum operations (dafault : None). When None it will be set 131 to 'default.qubit' 132 - encoding : str 133 string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude' 134 135 Returns: 136 -------- 137 Nothing, a RealAmplitudesCircuit object will be created. 138 ''' 139 super().__init__(n_qubits=n_qubits, n_layers=n_layers, dev=dev) 140 141 if encoding not in ['angle', 'amplitude']: raise(f"encoding can be angle or amplitude, found {encoding}") 142 143 self.encoding = encoding 144 self.weight_shape = {"weights": (n_layers, n_qubits, 3)} 145 self.circuit = self.circ(self.dev, self.n_qubits, self.n_layers, self.encoding)
RealAmplitudesCircuit constructor.
Parameters:
- n_qubits : int
number of qubits for the quantum circuit - n_layers : int
number of layers for the quantum circuit - dev : qml.device
PennyLane device on wich run quantum operations (dafault : None). When None it will be set to 'default.qubit' - encoding : str
string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude'
Returns:
Nothing, a RealAmplitudesCircuit object will be created.
@staticmethod
def
circ( dev: <module 'pennylane.devices' from '/Users/asebastianelli/miniforge3/envs/hqm/lib/python3.10/site-packages/pennylane/devices/__init__.py'>, n_qubits: int, n_layers: int, encoding: str) -> function:
147 @staticmethod 148 def circ(dev : qml.devices, n_qubits : int, n_layers : int, encoding : str) -> FunctionType: 149 ''' 150 RealAmplitudesCircuit static method that implements the quantum circuit. 151 152 Parameters: 153 ----------- 154 - dev : qml.device 155 PennyLane device on wich run quantum operations (dafault : None). When None it will be set 156 to 'default.qubit' 157 - n_qubits : int 158 number of qubits for the quantum circuit 159 - n_layers : int 160 number of layers for the quantum circuit 161 - encoding : str 162 string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude' 163 164 Returns: 165 -------- 166 - qnode : qml.qnode 167 the actual PennyLane circuit 168 ''' 169 @qml.qnode(dev) 170 def qnode(inputs : np.ndarray, weights : np.ndarray) -> list: 171 ''' 172 PennyLane based quantum circuit composed of an angle embedding layer and a basic entangler 173 layer. 174 175 Parameters: 176 ----------- 177 - inputs : np.ndarray 178 array containing input values (can came from previous torch/keras layers or quantum layers) 179 - weights : np.ndarray 180 array containing the weights of the circuit that are tuned during training, the shape of this 181 array depends on circuit's layers and qubits. 182 183 Returns: 184 -------- 185 - measurements : list 186 list of values measured from the quantum circuits 187 ''' 188 189 if encoding == 'angle': qml.AngleEmbedding(inputs, wires=range(n_qubits)) 190 if encoding == 'amplitude': qml.AmplitudeEmbedding(features=inputs, wires=range(n_qubits), normalize=True) 191 192 for q in range(n_qubits): qml.Hadamard(wires=q) 193 194 for n in range(n_layers): 195 for q1 in range(0, n_qubits): 196 for q2 in range(0, n_qubits): 197 if q1 < q2: 198 qml.CNOT(wires=[q2, q1]) 199 200 # Rot gates in the middle 201 for q in range(n_qubits): 202 qml.Rot(weights[n, q, 0], weights[n, q, 1], weights[n, q, 2], wires=q) 203 204 205 measurements = [qml.expval(qml.PauliZ(wires=i)) for i in range(n_qubits)] 206 return measurements 207 208 return qnode
RealAmplitudesCircuit static method that implements the quantum circuit.
Parameters:
- dev : qml.device
PennyLane device on wich run quantum operations (dafault : None). When None it will be set
to 'default.qubit' - n_qubits : int
number of qubits for the quantum circuit - n_layers : int
number of layers for the quantum circuit - encoding : str
string representing the type of input data encoding in quantum circuit, can be 'angle' or 'amplitude'
Returns:
- qnode : qml.qnode
the actual PennyLane circuit