1010import numpy as np
1111
1212from .abstractcircuit import AbstractCircuit
13- from .cons import backend , dtypestr , rdtypestr
13+ from .cons import backend , dtypestr , rdtypestr , idtypestr
1414from .quantum import sample2all
1515from .utils import arg_alias
1616
1717Tensor = Any
1818
1919
2020class U1Circuit (AbstractCircuit ):
21+ """
22+ Circuit class for U(1) conserving circuits (particle number conservation).
23+ Note: Currently only supports nqubits < 64 due to the use of 64-bit integer
24+ bitmasks for basis state representation.
25+ """
26+
2127 def __init__ (
2228 self ,
2329 nqubits : int ,
@@ -26,6 +32,10 @@ def __init__(
2632 inputs : Optional [Any ] = None ,
2733 ) -> None :
2834 self ._nqubits = nqubits
35+ if nqubits >= 64 :
36+ raise ValueError (
37+ f"U1Circuit only supports nqubits < 64, but got { nqubits } . "
38+ )
2939
3040 # Infer k from filled if not provided
3141 if k is None and filled is None :
@@ -53,7 +63,7 @@ def __init__(
5363
5464 # Convert basis to backend tensor for faster lookup
5565 self ._basis_tensor = backend .cast (
56- backend .convert_to_tensor (self ._basis ), dtype = "int32"
66+ backend .convert_to_tensor (self ._basis ), dtype = idtypestr
5767 )
5868
5969 if inputs is not None :
@@ -70,7 +80,7 @@ def __init__(
7080 # Find the index in our basis - JIT FRIENDLY
7181 # Use searchsorted and one_hot to stay within the graph
7282 fs_tensor = backend .cast (
73- backend .convert_to_tensor ([filled_state ]), dtype = "int32"
83+ backend .convert_to_tensor ([filled_state ]), dtype = idtypestr
7484 )
7585 initial_idx = backend .searchsorted (self ._basis_tensor , fs_tensor )[0 ]
7686 # Clip index for safety - searchsorted should always find exact match
@@ -419,7 +429,7 @@ def to_dense(self) -> Tensor:
419429 # Scatter the U(1) state into the full space at basis positions
420430 # indices should be shape [n, 1] for 1D scatter
421431 indices = backend .reshape (
422- backend .cast (self ._basis_tensor , "int32" ), [self ._dim , 1 ]
432+ backend .cast (self ._basis_tensor , idtypestr ), [self ._dim , 1 ]
423433 )
424434 dense_state = backend .scatter (dense_state , indices , self ._state )
425435 return dense_state
@@ -517,7 +527,7 @@ def sample(
517527
518528 # Use sample2all for format conversion
519529 # full_indices are already integers representing the full basis states
520- ch = backend .cast (full_indices , "int32" )
530+ ch = backend .cast (full_indices , idtypestr )
521531 return sample2all (
522532 ch ,
523533 n = self ._nqubits ,
0 commit comments