Skip to content

circuit/index.py

class Mode

Execution mode for the circuit: statevector (VECTOR) or density-matrix (MATRIX).

nametypedefault
MATRIXNone'matrix'
VECTORNone'vector'

class Frame

Lightweight record of a circuit operation (gate name, target indices, local dims, and parameters).

nametypedefault
dimU[int, Array]None
indexList[int]None
namestrNone
paramsDict[str, Any]None

init

Create an operation frame describing a gate acting on index with given local dim and params.

py
def __init__(self: Any, dim: U[int, Array], index: List[int], name: str, params: Optional[Dict[str, Any]]) -> Any
Implementation
python
def __init__(self, dim: U[int, Array], index: List[int], name: str, params: Optional[Dict[str, Any]]=None):
    self.index = index
    self.dim = dim
    self.name = name
    self.params = params or {}

parse

Extract a small, human-readable parameter subset (e.g. angles/indices) for display/logging.

py
def parse(kwargs: Dict[str, Any]) -> Dict[str, Any] [static]
Implementation
python
def parse(kwargs: Dict[str, Any]) -> Dict[str, Any]:
    valid = ['i', 'j', 'k', 'angle', 'type']
    params: Dict[str, Any] = {}
    for key in valid:
        if key in kwargs:
            val = kwargs[key]
            if isinstance(val, torch.Tensor):
                val = val.item()
            if isinstance(val, float):
                val = round(val, 4)
            params[key] = val
    return params

create

Create a Frame from a gate-like input, inferring a display name and capturing key params.

py
def create(gate_in: Any, dims: List[int], index: List[int]) -> 'Frame' [static]
Implementation
python
def create(gate_in: Any, dims: List[int], index: List[int], **kwargs: Any) -> 'Frame':
    params = Frame.parse(kwargs)
    name = ''
    if hasattr(gate_in, 'name'):
        name = gate_in.name
    elif hasattr(gate_in, '__name__'):
        name = gate_in.__name__
    else:
        name = 'U'
    return Frame(dim=dims, index=index, name=name, params=params)

class Circuit

A qudit circuit as an nn.Module applying a sequence of embedded unitaries. In VECTOR (default) mode it applies

|ψUmU2U1|ψ,

whereas in MATRIX mode it applies the unitary channel,

ρUmU2U1ρU1U2Um.

nametypedefault
circuitnn.SequentialNone
devicestrNone
dimU[int, Array]None
dims_List[int]None
gate_genAnyNone
gatesDict[int, Gategen]None
modeModeNone
operationsList[Frame]None
widthintNone
wiresintNone

init

Initialize a circuit with wires subsystems of local dimension(s) dim on device.

py
def __init__(self: Any, wires: int, dim: U[int, Array], device: str, mode: U[Mode, str]) -> Any
Implementation
python
def __init__(self, wires: int=2, dim: U[int, Array]=2, device: str='cpu', mode: U[Mode, str]=Mode.VECTOR):
    super(Circuit, self).__init__()
    if isinstance(mode, str):
        mode = mode.lower()
    self.mode = Mode(mode)
    if isinstance(dim, int):
        self.dims_ = [dim] * wires
    elif isinstance(dim, list):
        if len(dim) != wires:
            raise ValueError(f'Dim list {len(dim)} != wires {wires}.')
        self.dims_ = dim
    self.dim = dim
    self.width = int(np.prod(self.dims_))
    self.wires = wires
    self.device = device
    self.circuit = nn.Sequential()
    self.operations = []
    udits = sorted(list(set(self.dims_)))
    self.gates = {}
    for d in udits:
        self.gates[d] = Gategen(dim=d, device=device)
    if isinstance(self.dim, int):
        self.gate_gen = self.gates[self.dim]

gate

Append a gate acting on index to the circuit with optionally params

Gate may be of type Unitary, Gate, torch.Tensor, or a callable factory for an embedded Unitary.

The gate is added to the circuit as an nn.Module and a Frame is recorded for display/logging.

py
def gate(self: Any, gate_in: Any, index: Any) -> None
Implementation
python
def gate(self, gate_in: Any, index: Any, **kwargs: Any) -> None:
    if 'device' not in kwargs:
        kwargs['device'] = self.device
    idx_list = index if isinstance(index, list) else [index]
    dims = [self.dims_[i] for i in idx_list]
    self.operations.append(Frame.create(gate_in, dims, idx_list, **kwargs))
    Instance: Any = None
    if isinstance(gate_in, (torch.Tensor, Gate)):
        Instance = Unitary(matrix=gate_in, index=idx_list, wires=self.wires, dim=self.dims_, device=self.device)
    elif callable(gate_in):
        Instance = gate_in(dim=self.dims_, wires=self.wires, index=idx_list, **kwargs)
    else:
        raise TypeError(f'Unsupported gate input: {type(gate_in)}')
    pos = str(len(self.circuit))
    self.circuit.add_module(pos, Instance)

forward

Apply the circuit to a statevector or density matrix depending on self.mode.

py
def forward(self: Any, x: Any) -> torch.Tensor
Implementation
python
def forward(self, x: Any) -> torch.Tensor:
    if isinstance(x, np.ndarray):
        x = torch.from_numpy(x).to(dtype=C64, device=self.device)
    elif not isinstance(x, torch.Tensor):
        x = torch.tensor(x, dtype=C64, device=self.device)
    else:
        x = x.to(dtype=C64, device=self.device)
    if self.mode == Mode.VECTOR:
        return self.circuit(x)
    else:
        W = self.width
        if x.dim() == 1 or (x.dim() == 2 and min(x.shape) == 1):
            psi = x.reshape(W, 1)
            rho = psi @ psi.conj().T
        else:
            rho = x
        for module in self.circuit:
            rho = module.forwardd(rho)
        return rho

matrix

Materialize the full unitary matrix by acting on the computational basis vectors.

py
def matrix(self: Any) -> torch.Tensor
Implementation
python
def matrix(self) -> torch.Tensor:
    W = self.width
    I = torch.eye(W, dtype=C64, device=self.device)
    cols = []
    for i in range(W):
        cols.append(self.circuit(I[i]))
    return torch.cat(cols, dim=1)

draw

Render a simple textual diagram of the circuit; currently supports mode='ascii'.

py
def draw(self: Any, mode: str) -> Any
Implementation
python
def draw(self, mode: str='ascii') -> Any:
    from .transform import Table
    table = Table(self)
    if mode == 'ascii':
        return table.draw(self)
    return table.draw(self)