pqc to qiskit conversion

This commit is contained in:
Noa Aarts 2026-03-18 10:22:44 +01:00
parent e774575604
commit 93deb42c27
Signed by: noa
GPG key ID: 1850932741EFF672
2 changed files with 73 additions and 2 deletions

View file

@ -39,6 +39,17 @@ class QuantumType(enum.Enum):
QuantumType.RZ,
}
def is_parameterized(self):
return self in {
QuantumType.RX,
QuantumType.RXX,
QuantumType.RY,
QuantumType.RYY,
QuantumType.RZ,
QuantumType.RZZ,
QuantumType.CRX,
}
@dataclass(frozen=True)
class QuantumGate:
@ -59,6 +70,9 @@ class ParametrizedQuantumCircuit:
gates: list[list[QuantumGate]]
"""Gates in the quantum circuit, organised as a list of layers of gates."""
parameters: int
"""How many parameters are used the circuit"""
_expressivity: float | None = None
"""
Expressivity of the circuit, following the definition from {THE PAPER}
@ -90,6 +104,9 @@ class ParametrizedQuantumCircuit:
"""
Add a layer to the end of the existing circuit in-place
"""
for gate in layer:
if gate.type.is_parameterized():
self.parameters += 1
self.gates.append(layer)
@property

View file

@ -1,11 +1,65 @@
from typing import TYPE_CHECKING
from qiskit import QuantumCircuit
from qiskit.circuit.parameter import Parameter
from qiskit.circuit.parametervector import ParameterVector
if TYPE_CHECKING:
from quantum_circuit import ParametrizedQuantumCircuit
from quantum_circuit import (ParametrizedQuantumCircuit, QuantumGate,
QuantumType)
def add_qubit_gate(circ: QuantumCircuit, gate: QuantumGate, theta: Parameter) -> int:
match gate.type:
case QuantumType.Identity:
return 0
case QuantumType.Hadamard:
circ.h(gate.qubits[0])
return 0
case QuantumType.X:
circ.x(gate.qubits[0])
return 0
case QuantumType.RX:
circ.rx(theta, gate.qubits[0])
return 1
case QuantumType.RXX:
circ.rxx(theta, gate.qubits[0], gate.qubits[1]) # ty:ignore[index-out-of-bounds]
return 1
case QuantumType.Y:
circ.y(gate.qubits[0])
return 0
case QuantumType.RY:
circ.ry(theta, gate.qubits[0])
return 1
case QuantumType.RYY:
circ.ryy(theta, gate.qubits[0], gate.qubits[1]) # ty:ignore[index-out-of-bounds]
return 1
case QuantumType.Z:
circ.z(gate.qubits[0])
return 0
case QuantumType.RZ:
circ.rz(theta, gate.qubits[0])
return 1
case QuantumType.RZZ:
circ.rzz(theta, gate.qubits[0], gate.qubits[1]) # ty:ignore[index-out-of-bounds]
return 1
case QuantumType.CRX:
circ.crx(theta, gate.qubits[0], gate.qubits[1]) # ty:ignore[index-out-of-bounds]
return 1
case QuantumType.CX:
circ.cx(gate.qubits[0], gate.qubits[1]) # ty:ignore[index-out-of-bounds]
return 0
raise NotImplementedError
def build_qiskit_circ(pqc: "ParametrizedQuantumCircuit") -> tuple[QuantumCircuit, ParameterVector]:
raise NotImplementedError
circ = QuantumCircuit(pqc.qubits)
thetas = ParameterVector("thetas", circ.parameters)
current_theta_index = 0
for layer in pqc.gates:
for gate in layer:
current_theta_index += add_qubit_gate(circ, gate, thetas[current_theta_index])
return circ, thetas