qubosolver.bitstrings
qubosolver.Bitstrings
module-attribute
Section titled “
qubosolver.Bitstrings
module-attribute
”Bitstrings: TypeAlias = jaxtyping.Int8[torch.Tensor, 'n m']2-D int8 tensor of shape (n, m) representing a batch of n bitstrings each of
length m.
qubosolver.bitstrings
Section titled “
qubosolver.bitstrings
”Batch bitstring utilities for QUBO solvers.
A Bitstrings collection is a 2-D torch.int8 tensor of shape
(count, n_bits), where each row is an individual bitstring.
This module provides factory functions and converters for creating and
manipulating batches of bitstrings on the globally configured torch device.
Typical usage:
bs = bitstrings.from_strings(["1010", "0110", "1100"])ss = bitstrings.to_strings(bs) # ["1010", "0110", "1100"]z = bitstrings.zeros(4, 8) # 4 zero bitstrings of length 8f = bitstrings.round([[1.0, 0.0, 0.9999999]]) # from a MIP solver's outputSee also qubosolver.bitstring for single-bitstring operations.
Functions:
-
as_tensor–Convenience wrapper for
torch.as_tensorthat converts data to a bitstrings tensor. -
device–Returns the globally configured torch device.
-
dtype–Returns the dtype used for bitstrings (
torch.int8). -
from_strings–Creates a 2-D bitstrings tensor from a sequence of '0'/'1' strings.
-
rand–Creates a 2-D bitstrings tensor with independent uniformly random bits.
-
round–Rounds near-integral float values to a 2-D bitstrings tensor.
-
tensor–Creates a 2-D bitstrings tensor from the given data.
-
to_strings–Converts a 2-D bitstrings tensor into a list of '0'/'1' strings.
-
zeros–Creates a zero-filled 2-D bitstrings tensor.
-
zeros_field–Creates a dataclass field defaulting to a zero-filled bitstrings tensor.
as_tensor
Section titled “
as_tensor
”as_tensor(data: Any) -> qubosolver.Bitstrings
module-attribute (qubosolver.types.linalg.Bitstrings)" href="#qubosolver.Bitstrings">BitstringsConvenience wrapper for torch.as_tensor that converts data to a bitstrings tensor.
Avoids a copy when possible. If data is already a tensor with the right dtype and on
the right device, it is returned as-is, sharing the same underlying memory. A numpy
array is also shared rather than copied if it already has int8 dtype and the global
device is cpu (numpy arrays only live on CPU, so any other dtype or device forces a
copy). Lists, tuples, and other array-like inputs are always copied.
Parameters:
-
data(Any (external)) –Input data (tensor, numpy array, nested list, etc.).
Returns:
-
Bitstrings–A 2-D
int8tensor on the global device.
Source code in qubosolver/types/bitstrings.py
def as_tensor(data: Any) -> Bitstrings: # noqa: ANN401 (array-like input forwarded to torch.as_tensor) """Convenience wrapper for `torch.as_tensor` that converts data to a bitstrings tensor.
Avoids a copy when possible. If *data* is already a tensor with the right dtype and on the right device, it is returned as-is, sharing the same underlying memory. A numpy array is also shared rather than copied if it already has ``int8`` dtype and the global device is ``cpu`` (numpy arrays only live on CPU, so any other dtype or device forces a copy). Lists, tuples, and other array-like inputs are always copied.
Args: data: Input data (tensor, numpy array, nested list, etc.).
Returns: A 2-D ``int8`` tensor on the global device. """ return torch.as_tensor(data, dtype=dtype(), device=device())
device
Section titled “
device
”device() -> torch.deviceReturns the globally configured torch device.
Source code in qubosolver/types/bitstrings.py
def device() -> torch.device: """Returns the globally configured torch device.""" return linalg.device()
dtype
Section titled “
dtype
”dtype() -> torch.dtypeReturns the dtype used for bitstrings (torch.int8).
Source code in qubosolver/types/bitstrings.py
def dtype() -> torch.dtype: """Returns the dtype used for bitstrings (``torch.int8``).""" return torch.int8
from_strings
Section titled “
from_strings
”from_strings(strings: Sequence[str], *, device: torch.device | None = None) -> qubosolver.Bitstrings
module-attribute (qubosolver.types.linalg.Bitstrings)" href="#qubosolver.Bitstrings">BitstringsCreates a 2-D bitstrings tensor from a sequence of '0'/'1' strings.
Parameters:
-
strings(Sequence (external)[str (external)]) –A sequence of strings, each consisting of '0' and '1' characters. All strings must have the same length.
-
device(torch (external).device (external) | None, default:None) –Torch device for the tensor.
Returns:
-
Bitstrings–A 2-D
int8tensor of shape(len(strings), len(strings[0])), possibly empty.
Raises:
-
ValueError (external)–If the strings have differing lengths.
Source code in qubosolver/types/bitstrings.py
def from_strings(strings: Sequence[str], *, device: torch.device | None = None) -> Bitstrings: """Creates a 2-D bitstrings tensor from a sequence of '0'/'1' strings.
Args: strings: A sequence of strings, each consisting of '0' and '1' characters. All strings must have the same length. device: Torch device for the tensor.
Returns: A 2-D ``int8`` tensor of shape ``(len(strings), len(strings[0]))``, possibly empty.
Raises: ValueError: If the strings have differing lengths. """ device = device or _device() if len(strings) == 0: return zeros(0, 0, device=device) lengths = {len(s) for s in strings} if len(lengths) != 1: raise ValueError( f"All bitstrings must have the same length, got lengths: {sorted(lengths)}" ) return tensor([[int(c) for c in s] for s in strings], device=device)rand(count: int, n_bits: int, *, device: torch.device | None = None, rng: torch.Generator | None = None) -> qubosolver.Bitstrings
module-attribute (qubosolver.types.linalg.Bitstrings)" href="#qubosolver.Bitstrings">BitstringsCreates a 2-D bitstrings tensor with independent uniformly random bits.
Parameters:
-
count(int (external)) –Number of bitstrings (rows).
-
n_bits(int (external)) –Length of each bitstring (columns).
-
device(torch (external).device (external) | None, default:None) –Torch device for the tensor.
-
rng(torch (external).Generator (external) | None, default:None) –PyTorch random number generator controlling the sampling.
Returns:
-
Bitstrings–A 2-D
int8tensor of shape(count, n_bits)containing 0s and 1s.
Source code in qubosolver/types/bitstrings.py
def rand( count: int, n_bits: int, *, device: torch.device | None = None, rng: torch.Generator | None = None,) -> Bitstrings: """Creates a 2-D bitstrings tensor with independent uniformly random bits.
Args: count: Number of bitstrings (rows). n_bits: Length of each bitstring (columns). device: Torch device for the tensor. rng: PyTorch random number generator controlling the sampling.
Returns: A 2-D ``int8`` tensor of shape ``(count, n_bits)`` containing 0s and 1s. """ device = device or _device() rng = rng or torch_rng() return torch.randint(0, 2, (count, n_bits), generator=rng, device=device, dtype=dtype())
round
Section titled “
round
”round(data: Any, *, atol: float = 1e-06, device: torch.device | None = None) -> qubosolver.Bitstrings
module-attribute (qubosolver.types.linalg.Bitstrings)" href="#qubosolver.Bitstrings">BitstringsRounds near-integral float values to a 2-D bitstrings tensor.
Values are compared in float64 regardless of the globally configured
float dtype, so atol keeps its meaning even when the global dtype is
narrower (e.g. float32, which would round 0.9999999998 to exactly
1.0 before the check could see it).
Parameters:
-
data(Any (external)) –Input data (tensor, numpy array, nested list, etc.) of floats, each within atol of 0 or 1. Nested sequences must not be ragged.
-
atol(float (external), default:1e-06) –Maximum absolute distance from 0 or 1 tolerated before raising.
-
device(torch (external).device (external) | None, default:None) –Torch device for the tensor.
Returns:
-
Bitstrings–A 2-D
int8tensor of shape(count, n_bits).
Raises:
-
ValueError (external)–If any value is further than atol from both 0 and 1, or if the input is a ragged nested sequence.
Source code in qubosolver/types/bitstrings.py
def round( data: Any, # noqa: ANN401 (array-like input forwarded to torch.as_tensor) *, atol: float = 1e-6, device: torch.device | None = None,) -> Bitstrings: """Rounds near-integral float values to a 2-D bitstrings tensor.
Values are compared in ``float64`` regardless of the globally configured float dtype, so *atol* keeps its meaning even when the global dtype is narrower (e.g. ``float32``, which would round ``0.9999999998`` to exactly ``1.0`` before the check could see it).
Args: data: Input data (tensor, numpy array, nested list, etc.) of floats, each within *atol* of 0 or 1. Nested sequences must not be ragged. atol: Maximum absolute distance from 0 or 1 tolerated before raising. device: Torch device for the tensor.
Returns: A 2-D ``int8`` tensor of shape ``(count, n_bits)``.
Raises: ValueError: If any value is further than *atol* from both 0 and 1, or if the input is a ragged nested sequence. """ device = device or _device() values = torch.as_tensor(data, dtype=torch.float64) bits = torch.round(values) invalid = ((bits != 0) & (bits != 1)) | ((values - bits).abs() > atol) if bool(invalid.any()): raise ValueError( f"Expected values within {atol} of 0 or 1, got " f"{values[invalid].tolist()} in {values.tolist()}" ) if bits.shape == (0,): # `torch.as_tensor([])` is 1-D: keep empty bitstrings 2-D. bits = bits.reshape(0, 0) return bits.to(dtype=dtype(), device=device)
tensor
Section titled “
tensor
”tensor(data: Any, *, device: torch.device | None = None, **kwargs: Any) -> qubosolver.Bitstrings
module-attribute (qubosolver.types.linalg.Bitstrings)" href="#qubosolver.Bitstrings">BitstringsCreates a 2-D bitstrings tensor from the given data.
Parameters:
-
data(Any (external)) –Input data (nested list or array-like of 0s and 1s).
-
device(torch (external).device (external) | None, default:None) –Torch device for the tensor.
-
**kwargs(Any (external), default:{}) –Extra keyword arguments forwarded to
torch.tensor.
Returns:
-
Bitstrings–A 2-D
int8tensor; an empty list gives a(0, 0)tensor.
Source code in qubosolver/types/bitstrings.py
def tensor( data: Any, # noqa: ANN401 (array-like input forwarded to torch.tensor) *, device: torch.device | None = None, **kwargs: Any, # noqa: ANN401 (forwarded to torch.tensor)) -> Bitstrings: """Creates a 2-D bitstrings tensor from the given data.
Args: data: Input data (nested list or array-like of 0s and 1s). device: Torch device for the tensor. **kwargs: Extra keyword arguments forwarded to `torch.tensor`.
Returns: A 2-D ``int8`` tensor; an empty list gives a ``(0, 0)`` tensor. """ device = device or _device() result = torch.tensor(data, dtype=dtype(), device=device, **kwargs) # `torch.tensor([])` is 1-D: keep empty bitstrings 2-D. return result.reshape(0, 0) if result.shape == (0,) else result
to_strings
Section titled “
to_strings
”to_strings(bitstrings: qubosolver.Bitstrings
module-attribute (qubosolver.types.linalg.Bitstrings)" href="#qubosolver.Bitstrings">Bitstrings) -> list[str]Converts a 2-D bitstrings tensor into a list of '0'/'1' strings.
Parameters:
-
bitstrings(Bitstrings) –A 2-D
int8tensor of shape(n, m)containing 0s and 1s.
Returns:
-
list (external)[str (external)]–A list of n strings, each of length m, representing each row of the tensor.
Source code in qubosolver/types/bitstrings.py
def to_strings(bitstrings: Bitstrings) -> list[str]: """Converts a 2-D bitstrings tensor into a list of '0'/'1' strings.
Args: bitstrings: A 2-D ``int8`` tensor of shape ``(n, m)`` containing 0s and 1s.
Returns: A list of *n* strings, each of length *m*, representing each row of the tensor. """ return ["".join(str(b.item()) for b in row) for row in bitstrings]
zeros
Section titled “
zeros
”zeros(count: int, n_bits: int, *, device: torch.device | None = None) -> qubosolver.Bitstrings
module-attribute (qubosolver.types.linalg.Bitstrings)" href="#qubosolver.Bitstrings">BitstringsCreates a zero-filled 2-D bitstrings tensor.
Parameters:
-
count(int (external)) –Number of bitstrings (rows).
-
n_bits(int (external)) –Length of each bitstring (columns).
-
device(torch (external).device (external) | None, default:None) –Torch device for the tensor.
Returns:
-
Bitstrings–A 2-D
int8tensor of shape(count, n_bits).
Source code in qubosolver/types/bitstrings.py
def zeros(count: int, n_bits: int, *, device: torch.device | None = None) -> Bitstrings: """Creates a zero-filled 2-D bitstrings tensor.
Args: count: Number of bitstrings (rows). n_bits: Length of each bitstring (columns). device: Torch device for the tensor.
Returns: A 2-D ``int8`` tensor of shape ``(count, n_bits)``. """ device = device or _device() return torch.zeros((count, n_bits), dtype=dtype(), device=device)
zeros_field
Section titled “
zeros_field
”zeros_field(count: int, n_bits: int, *, device: torch.device | None = None) -> qubosolver.Bitstrings
module-attribute (qubosolver.types.linalg.Bitstrings)" href="#qubosolver.Bitstrings">BitstringsCreates a dataclass field defaulting to a zero-filled bitstrings tensor.
Parameters:
-
count(int (external)) –Number of bitstrings (rows).
-
n_bits(int (external)) –Length of each bitstring (columns).
-
device(torch (external).device (external) | None, default:None) –Torch device for the tensor.
Returns:
-
Bitstrings–A dataclass field (typed as
Bitstringsfor the enclosing class) whose -
Bitstrings–default_factorybuilds a fresh zero tensor per instance.
Source code in qubosolver/types/bitstrings.py
@no_runtime_typecheckdef zeros_field(count: int, n_bits: int, *, device: torch.device | None = None) -> Bitstrings: """Creates a dataclass field defaulting to a zero-filled bitstrings tensor.
Args: count: Number of bitstrings (rows). n_bits: Length of each bitstring (columns). device: Torch device for the tensor.
Returns: A dataclass field (typed as `Bitstrings` for the enclosing class) whose `default_factory` builds a fresh zero tensor per instance. """ return field(default_factory=lambda: zeros(count, n_bits, device=device))