5454
5555import attrs
5656import numpy as np
57- import sympy
5857from fxpmath import Fxp
5958from numpy .typing import NDArray
6059
60+ from qualtran .symbolics import is_symbolic , SymbolicInt
61+
6162
6263class QDType (metaclass = abc .ABCMeta ):
6364 """This defines the abstract interface for quantum data types."""
@@ -89,7 +90,11 @@ def assert_valid_classical_val(self, val: Any, debug_str: str = 'val'):
8990 debug_str: Optional debugging information to use in exception messages.
9091 """
9192
92- def iteration_length_or_zero (self ) -> Union [int , sympy .Expr ]:
93+ @abc .abstractmethod
94+ def is_symbolic (self ) -> bool :
95+ """Returns True if this qdtype is parameterized with symbolic objects."""
96+
97+ def iteration_length_or_zero (self ) -> SymbolicInt :
9398 """Safe version of iteration length.
9499
95100 Returns the iteration_length if the type has it or else zero.
@@ -130,6 +135,9 @@ def assert_valid_classical_val(self, val: int, debug_str: str = 'val'):
130135 if not (val == 0 or val == 1 ):
131136 raise ValueError (f"Bad { self } value { val } in { debug_str } " )
132137
138+ def is_symbolic (self ) -> bool :
139+ return False
140+
133141 def to_bits (self , x ) -> List [int ]:
134142 """Yields individual bits corresponding to binary representation of x"""
135143 self .assert_valid_classical_val (x )
@@ -154,7 +162,7 @@ def __str__(self):
154162class QAny (QDType ):
155163 """Opaque bag-of-qbits type."""
156164
157- bitsize : Union [ int , sympy . Expr ]
165+ bitsize : SymbolicInt
158166
159167 @property
160168 def num_qubits (self ):
@@ -171,6 +179,9 @@ def from_bits(self, bits: Sequence[int]) -> int:
171179 # TODO: Raise an error once usage of `QAny` is minimized across the library
172180 return QUInt (self .bitsize ).from_bits (bits )
173181
182+ def is_symbolic (self ) -> bool :
183+ return is_symbolic (self .bitsize )
184+
174185 def assert_valid_classical_val (self , val , debug_str : str = 'val' ):
175186 pass
176187
@@ -188,12 +199,15 @@ class QInt(QDType):
188199 bitsize: The number of qubits used to represent the integer.
189200 """
190201
191- bitsize : Union [ int , sympy . Expr ]
202+ bitsize : SymbolicInt
192203
193204 @property
194205 def num_qubits (self ):
195206 return self .bitsize
196207
208+ def is_symbolic (self ) -> bool :
209+ return is_symbolic (self .bitsize )
210+
197211 def get_classical_domain (self ) -> Iterable [int ]:
198212 max_val = 1 << (self .bitsize - 1 )
199213 return range (- max_val , max_val )
@@ -240,7 +254,7 @@ class QIntOnesComp(QDType):
240254 bitsize: The number of qubits used to represent the integer.
241255 """
242256
243- bitsize : Union [ int , sympy . Expr ]
257+ bitsize : SymbolicInt
244258
245259 def __attrs_post_init__ (self ):
246260 if isinstance (self .bitsize , int ):
@@ -251,6 +265,9 @@ def __attrs_post_init__(self):
251265 def num_qubits (self ):
252266 return self .bitsize
253267
268+ def is_symbolic (self ) -> bool :
269+ return is_symbolic (self .bitsize )
270+
254271 def to_bits (self , x : int ) -> List [int ]:
255272 """Yields individual bits corresponding to binary representation of x"""
256273 self .assert_valid_classical_val (x )
@@ -286,12 +303,15 @@ class QUInt(QDType):
286303 bitsize: The number of qubits used to represent the integer.
287304 """
288305
289- bitsize : Union [ int , sympy . Expr ]
306+ bitsize : SymbolicInt
290307
291308 @property
292309 def num_qubits (self ):
293310 return self .bitsize
294311
312+ def is_symbolic (self ) -> bool :
313+ return is_symbolic (self .bitsize )
314+
295315 def get_classical_domain (self ) -> Iterable [Any ]:
296316 return range (2 ** self .bitsize )
297317
@@ -371,11 +391,11 @@ class BoundedQUInt(QDType):
371391 iteration_length: The length of the iteration range.
372392 """
373393
374- bitsize : Union [ int , sympy . Expr ]
375- iteration_length : Union [ int , sympy . Expr ] = attrs .field ()
394+ bitsize : SymbolicInt
395+ iteration_length : SymbolicInt = attrs .field ()
376396
377397 def __attrs_post_init__ (self ):
378- if isinstance ( self .bitsize , int ):
398+ if not self .is_symbolic ( ):
379399 if self .iteration_length > 2 ** self .bitsize :
380400 raise ValueError (
381401 "BoundedQUInt iteration length is too large for given bitsize. "
@@ -386,6 +406,9 @@ def __attrs_post_init__(self):
386406 def _default_iteration_length (self ):
387407 return 2 ** self .bitsize
388408
409+ def is_symbolic (self ) -> bool :
410+ return is_symbolic (self .bitsize , self .iteration_length )
411+
389412 @property
390413 def num_qubits (self ):
391414 return self .bitsize
@@ -446,16 +469,16 @@ class QFxp(QDType):
446469 number of integer bits is reduced by 1.
447470 """
448471
449- bitsize : Union [ int , sympy . Expr ]
450- num_frac : Union [ int , sympy . Expr ]
472+ bitsize : SymbolicInt
473+ num_frac : SymbolicInt
451474 signed : bool = False
452475
453476 @property
454477 def num_qubits (self ):
455478 return self .bitsize
456479
457480 @property
458- def num_int (self ) -> Union [ int , sympy . Expr ] :
481+ def num_int (self ) -> SymbolicInt :
459482 return self .bitsize - self .num_frac - int (self .signed )
460483
461484 @property
@@ -466,6 +489,9 @@ def fxp_dtype_str(self) -> str:
466489 def _fxp_dtype (self ) -> Fxp :
467490 return Fxp (None , dtype = self .fxp_dtype_str )
468491
492+ def is_symbolic (self ) -> bool :
493+ return is_symbolic (self .bitsize , self .num_frac )
494+
469495 def to_bits (self , x : Union [float , Fxp ]) -> List [int ]:
470496 """Yields individual bits corresponding to binary representation of x"""
471497 self ._assert_valid_classical_val (x )
@@ -539,12 +565,15 @@ class QMontgomeryUInt(QDType):
539565 [Montgomery modular multiplication](https://en.wikipedia.org/wiki/Montgomery_modular_multiplication)
540566 """
541567
542- bitsize : Union [ int , sympy . Expr ]
568+ bitsize : SymbolicInt
543569
544570 @property
545571 def num_qubits (self ):
546572 return self .bitsize
547573
574+ def is_symbolic (self ) -> bool :
575+ return is_symbolic (self .bitsize )
576+
548577 def get_classical_domain (self ) -> Iterable [Any ]:
549578 return range (2 ** self .bitsize )
550579
0 commit comments