Source code for qailab.circuit.encoding_blocks.rotational

 1"""R-gate implementations of input vector encoding blocks for variational circuits."""
 2from typing import Literal
 3from collections.abc import Callable
 4
 5from qiskit import QuantumCircuit
 6from qiskit.circuit.library import RealAmplitudes
 7
 8from qailab.circuit.base import EncodingBlock, EntanglingBlock
 9
10
[docs] 11class RotationalEncoder(EncodingBlock): 12 """ 13 Encoding of input vector using rotational gates. 14 15 Attributes: 16 r_gate_type (Literal['x', 'y', 'z']): Type of rotational gate applied to each qubit. 17 block_type (Literal['input', 'weight']): Whether this block encodes weights or inputs. 18 """ 19 20 def __init__(self, r_gate_type: Literal['x', 'y', 'z'], block_type: Literal['input', 'weight']) -> None: 21 self.r_gate_type: Literal['x', 'y', 'z'] = r_gate_type 22 super().__init__(f"R{r_gate_type}Encoder", block_type) 23 24 def _build_circuit(self, num_qubits: int) -> QuantumCircuit: 25 # Don't create new parameter vectors. This would enable the user to encode the same vector in different parts of the circuit. 26 if self._parameters is None: 27 self._parameters = self._create_parameters(num_qubits) 28 29 circuit = QuantumCircuit(num_qubits) 30 match self.r_gate_type: 31 case 'x': 32 fn = circuit.rx 33 case 'y': 34 fn = circuit.ry 35 case 'z': 36 fn = circuit.rz 37 case _: 38 raise ValueError(f"'{self.r_gate_type}' is not a valid rotational gate type") 39 for i in range(num_qubits): 40 fn(self._parameters[i], i) 41 42 return circuit
43 44
[docs] 45class RealAmplitudesBlock(EncodingBlock, EntanglingBlock): 46 """ 47 Block wrapper for RealAmplitudes from qiskit.circuit.library 48 """ 49 50 def __init__( 51 self, 52 block_type: Literal['input', 'weight'], 53 entanglement: str | list[list[int]] | Callable[[int], list[int]] = "reverse_linear", 54 reps: int = 3, 55 skip_final_rotation_layer: bool = False 56 ) -> None: 57 self.entanglement = entanglement 58 self.reps = reps 59 self.skip_final_rotation_layer = skip_final_rotation_layer 60 super().__init__("RealAmplitudesEncoder", block_type) 61 62 def _build_circuit(self, num_qubits: int) -> QuantumCircuit: 63 pv_name = self._create_parameters(1)[0].name 64 amplitudes = RealAmplitudes( 65 num_qubits, 66 parameter_prefix=pv_name, 67 entanglement=self.entanglement, 68 reps=self.reps, 69 skip_final_rotation_layer=self.skip_final_rotation_layer, 70 ) 71 self._parameters = list(amplitudes.parameters) 72 return amplitudes