Skip to content

Commit eb98ee1

Browse files
authored
Update circuit.py
1 parent 3c694c7 commit eb98ee1

File tree

1 file changed

+55
-44
lines changed

1 file changed

+55
-44
lines changed

core/circuit.py

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,62 @@
1+
from typing import List, Any, Dict, Optional, Union
12
import numpy as np
2-
from typing import List, Tuple, Dict, Any
33

4+
class CircuitComponent:
5+
"""Base class for anything that can be added to a quantum circuit."""
6+
7+
def apply_to_density_matrix(self, rho: np.ndarray, num_qubits: int, qubit_map: Dict[int, int]) -> np.ndarray:
8+
"""Must be implemented by subclasses to evolve the quantum state."""
9+
raise NotImplementedError("Subclasses must implement apply_to_density_matrix")
410

5-
class QuantumCircuit:
6-
"""Represents a quantum circuit as a sequence of operations."""
11+
def get_involved_qubit_local_ids(self) -> List[int]:
12+
"""Returns the list of qubits this component acts upon."""
13+
raise NotImplementedError
714

15+
class GateOperation(CircuitComponent):
16+
"""Represents a specific gate acting on specific qubits."""
17+
18+
def __init__(self, gate: Any, qubit_ids: List[int]):
19+
self.gate = gate
20+
self.qubit_ids = qubit_ids
21+
22+
def get_involved_qubit_local_ids(self) -> List[int]:
23+
return self.qubit_ids
24+
25+
def apply_to_density_matrix(self, rho: np.ndarray, num_qubits: int, qubit_map: Dict[int, int]) -> np.ndarray:
26+
# Map local circuit IDs to global backend IDs
27+
global_targets = [qubit_map[qid] for qid in self.qubit_ids]
28+
return self.gate.apply_to_density_matrix(rho, global_targets, num_qubits)
29+
30+
class QuantumCircuit(CircuitComponent):
31+
"""A collection of GateOperations and other CircuitComponents."""
32+
833
def __init__(self, num_qubits: int, name: str = "Circuit"):
934
self.num_qubits = num_qubits
1035
self.name = name
11-
self.operations: List[Tuple[Any, List[int]]] = []
12-
13-
def add_gate(self, gate, target_qubit_local_ids):
14-
"""Adds a gate to the circuit."""
15-
if not isinstance(target_qubit_local_ids, list):
16-
target_qubit_local_ids = [target_qubit_local_ids]
17-
self.operations.append((gate, target_qubit_local_ids))
18-
19-
def get_parameters(self) -> Dict[str, Any]:
20-
"""Aggregates all parameters from gates in the circuit."""
21-
params = {}
22-
for gate, _ in self.operations:
23-
params.update(gate.get_parameters())
24-
return params
25-
26-
def bind_parameters(self, bindings: Dict[str, float]):
27-
"""Binds numerical values to the circuit parameters."""
28-
for gate, _ in self.operations:
29-
gate.bind_parameters(bindings)
30-
31-
def get_visualization_info(self, offset_x: float, offset_y: float,
32-
qubit_y_coords: Dict[int, float]) -> List[Dict[str, Any]]:
33-
"""Returns a list of dictionaries for the CircuitDrawer."""
34-
info = []
35-
current_x = offset_x
36-
for gate, targets in self.operations:
37-
gate_info = {
38-
'type': 'gate',
39-
'name': gate.name,
40-
'num_qubits': len(targets),
41-
'x': current_x,
42-
'params': {k: p.get_value() for k, p in gate.params.items() if p.is_bound()}
43-
}
44-
if len(targets) == 1:
45-
gate_info['y'] = qubit_y_coords[targets[0]]
46-
elif len(targets) == 2:
47-
gate_info['control_y'] = qubit_y_coords[targets[0]]
48-
gate_info['target_y'] = qubit_y_coords[targets[1]]
49-
info.append(gate_info)
50-
current_x += 0.8
51-
return info
36+
# Use List[CircuitComponent] to ensure mypy can track apply_to_density_matrix
37+
self._components: List[CircuitComponent] = []
38+
39+
def add(self, component: CircuitComponent):
40+
"""Adds a component (Gate or Sub-circuit) to the circuit."""
41+
self._components.append(component)
42+
43+
def get_involved_qubit_local_ids(self) -> List[int]:
44+
"""Returns all qubits involved in this circuit's components."""
45+
involved = set()
46+
for comp in self._components:
47+
involved.update(comp.get_involved_qubit_local_ids())
48+
return sorted(list(involved))
49+
50+
def apply_to_density_matrix(self, rho: np.ndarray, num_qubits: int, qubit_map: Dict[int, int]) -> np.ndarray:
51+
"""Evolves the state through all components in the circuit."""
52+
for component in self._components:
53+
rho = component.apply_to_density_matrix(rho, num_qubits, qubit_map)
54+
return rho
55+
56+
def get_qiskit_circuit_instructions(self) -> List[Any]:
57+
"""Stub to satisfy external backend requirements (like Qiskit)."""
58+
instructions: List[Any] = []
59+
for comp in self._components:
60+
if hasattr(comp, 'get_qiskit_circuit_instructions'):
61+
instructions.extend(comp.get_qiskit_circuit_instructions())
62+
return instructions

0 commit comments

Comments
 (0)