Skip to content

Results are limited to the current section: Qoolqit

Product news

qoolqit

A Python library for algorithm development in the Rydberg Analog Model.

Modules:

Classes:

  • AnalogDevice –

    A realistic device for analog sequence execution.

  • AnalogDeviceWithDMM –

    A realistic device with DMM for analog sequence execution.

  • BlackmanWaveform –

    A Blackman window of a specified duration and area under the curve.

  • ConstantWaveform –

    A constant waveform over a given duration.

  • DelayWaveform –

    An empty waveform.

  • Device –

    QoolQit Device wrapper around a Pulser BaseDevice.

  • DigitalAnalogDevice –

    A device with digital and analog capabilities.

  • Drive –

    The drive Hamiltonian acting over a duration.

  • InterpolatedWaveform –

    A waveform created from shape-preserving interpolation of data points.

  • MockDevice –

    A virtual device for unconstrained prototyping.

  • PiecewiseLinearWaveform –

    A piecewise linear waveform.

  • QuantumProgram –

    A program representing a Sequence acting on a Register of qubits.

  • RampWaveform –

    A ramp that linearly interpolates between an initial and final value.

  • Register –

    A QoolQit register mapping qubit IDs to 2D coordinates.

  • SequenceCompiler –

    Compiles a QoolQit Register and Drive to a Device.

Functions:

AnalogDevice()

A realistic device for analog sequence execution.

Methods:

  • from_connection –

    Return the specified device from the selected device from a connection.

  • info –

    Show the device short description and constraints.

  • reset_converter –

    Resets the unit converter to the default one.

  • set_distance_unit –

    Changes the unit converter according to a reference distance unit.

  • set_energy_unit –

    Changes the unit converter according to a reference energy unit.

Attributes:

  • specs (dict[str, float | None]) –

    Return the device specification constraints.

Source code in qoolqit/devices/device.py
def __init__(self) -> None:
super().__init__(pulser_device=pulser.AnalogDevice)
specs: dict[str, float | None]

Return the device specification constraints.

from_connection(
connection: RemoteConnection, name: str
) -> Device (qoolqit.devices.device.Device)" href="#qoolqit.Device">Device

Return the specified device from the selected device from a connection.

Available devices through the provided connection are can be seen with the connection.fetch_available_devices() method.

Parameters:

  • connection (RemoteConnection) –

    connection object to fetch the available devices.

  • name (str) –

    The name of the desired device.

Returns:

  • Device ( Device ) –

    The requested device.

Raises:

  • ValueError –

    If the requested device is not available through the provided connection.

Example:

from pasqal_cloud import PasqalCloudConnection
fresnel_device = Device.from_connection(connection=PasqalCloudConnection(), name="FRESNEL")
Source code in qoolqit/devices/device.py
@classmethod
def from_connection(cls, connection: RemoteConnection, name: str) -> Device:
"""Return the specified device from the selected device from a connection.
Available devices through the provided connection are can be seen with
the `connection.fetch_available_devices()` method.
Args:
connection (RemoteConnection): connection object to fetch the available devices.
name (str): The name of the desired device.
Returns:
Device: The requested device.
Raises:
ValueError: If the requested device is not available through the provided connection.
Example:
```python
from pasqal_cloud import PasqalCloudConnection
fresnel_device = Device.from_connection(connection=PasqalCloudConnection(), name="FRESNEL")
```
"""
available_remote_devices = connection.fetch_available_devices()
if name not in available_remote_devices:
raise ValueError(f"Device {name} is not available through the provided connection.")
pulser_device = available_remote_devices[name]
return cls(pulser_device=pulser_device)
info() -> None

Show the device short description and constraints.

Source code in qoolqit/devices/device.py
def info(self) -> None:
"""Show the device short description and constraints."""
print(self)
reset_converter() -> None

Resets the unit converter to the default one.

Source code in qoolqit/devices/device.py
def reset_converter(self) -> None:
"""Resets the unit converter to the default one."""
# Create a NEW converter so mutations don't persist.
self._converter = self._default_converter
set_distance_unit(distance: float) -> None

Changes the unit converter according to a reference distance unit.

Source code in qoolqit/devices/device.py
def set_distance_unit(self, distance: float) -> None:
"""Changes the unit converter according to a reference distance unit."""
self.converter.factors = self.converter.factors_from_distance(distance)
set_energy_unit(energy: float) -> None

Changes the unit converter according to a reference energy unit.

Source code in qoolqit/devices/device.py
def set_energy_unit(self, energy: float) -> None:
"""Changes the unit converter according to a reference energy unit."""
self.converter.factors = self.converter.factors_from_energy(energy)
AnalogDeviceWithDMM()

A realistic device with DMM for analog sequence execution.

Methods:

  • from_connection –

    Return the specified device from the selected device from a connection.

  • info –

    Show the device short description and constraints.

  • reset_converter –

    Resets the unit converter to the default one.

  • set_distance_unit –

    Changes the unit converter according to a reference distance unit.

  • set_energy_unit –

    Changes the unit converter according to a reference energy unit.

Attributes:

  • specs (dict[str, float | None]) –

    Return the device specification constraints.

Source code in qoolqit/devices/device.py
def __init__(self) -> None:
dmm_channel = pulser.channels.dmm.DMM(
clock_period=4,
min_duration=16,
max_duration=6000,
mod_bandwidth=8,
bottom_detuning=-2 * math.pi * 20,
total_bottom_detuning=-2 * math.pi * 20,
)
# Create a virtual device that can be modified to add a DMM channel.
pulser_virtual_device = pulser.AnalogDevice.to_virtual()
pulser_device = replace(
pulser_virtual_device, dmm_objects=(dmm_channel,), name="AnalogDeviceWithDMM"
)
super().__init__(pulser_device=pulser_device)
specs: dict[str, float | None]

Return the device specification constraints.

from_connection(
connection: RemoteConnection, name: str
) -> Device (qoolqit.devices.device.Device)" href="#qoolqit.Device">Device

Return the specified device from the selected device from a connection.

Available devices through the provided connection are can be seen with the connection.fetch_available_devices() method.

Parameters:

  • connection (RemoteConnection) –

    connection object to fetch the available devices.

  • name (str) –

    The name of the desired device.

Returns:

  • Device ( Device ) –

    The requested device.

Raises:

  • ValueError –

    If the requested device is not available through the provided connection.

Example:

from pasqal_cloud import PasqalCloudConnection
fresnel_device = Device.from_connection(connection=PasqalCloudConnection(), name="FRESNEL")
Source code in qoolqit/devices/device.py
@classmethod
def from_connection(cls, connection: RemoteConnection, name: str) -> Device:
"""Return the specified device from the selected device from a connection.
Available devices through the provided connection are can be seen with
the `connection.fetch_available_devices()` method.
Args:
connection (RemoteConnection): connection object to fetch the available devices.
name (str): The name of the desired device.
Returns:
Device: The requested device.
Raises:
ValueError: If the requested device is not available through the provided connection.
Example:
```python
from pasqal_cloud import PasqalCloudConnection
fresnel_device = Device.from_connection(connection=PasqalCloudConnection(), name="FRESNEL")
```
"""
available_remote_devices = connection.fetch_available_devices()
if name not in available_remote_devices:
raise ValueError(f"Device {name} is not available through the provided connection.")
pulser_device = available_remote_devices[name]
return cls(pulser_device=pulser_device)
info() -> None

Show the device short description and constraints.

Source code in qoolqit/devices/device.py
def info(self) -> None:
"""Show the device short description and constraints."""
print(self)
reset_converter() -> None

Resets the unit converter to the default one.

Source code in qoolqit/devices/device.py
def reset_converter(self) -> None:
"""Resets the unit converter to the default one."""
# Create a NEW converter so mutations don't persist.
self._converter = self._default_converter
set_distance_unit(distance: float) -> None

Changes the unit converter according to a reference distance unit.

Source code in qoolqit/devices/device.py
def set_distance_unit(self, distance: float) -> None:
"""Changes the unit converter according to a reference distance unit."""
self.converter.factors = self.converter.factors_from_distance(distance)
set_energy_unit(energy: float) -> None

Changes the unit converter according to a reference energy unit.

Source code in qoolqit/devices/device.py
def set_energy_unit(self, energy: float) -> None:
"""Changes the unit converter according to a reference energy unit."""
self.converter.factors = self.converter.factors_from_energy(energy)
BlackmanWaveform(duration: float, area: float)

A Blackman window of a specified duration and area under the curve.

Implements the positive Blackman window shaped waveform blackman(t) = A(0.42 - 0.5cos(αt) + 0.08cos(2αt)) A = area/(0.42duration) α = 2π/duration

See: https://en.wikipedia.org/wiki/Window_function#:~:text=Blackman%20window (external)

Parameters:

  • duration (float) –

    The waveform duration.

  • area (float) –

    The integral of the waveform.

Example
blackman_wf = BlackmanWaveform(100.0, area=3.14)

Methods:

  • __rmul__ –

    Rescale this waveform by a scalar (right-hand multiplication).

  • __rshift__ –

    Returns a new CompositeWaveform composed of this waveform and another.

Attributes:

  • duration (float) –

    Returns the duration of the waveform.

  • params (dict[str, float | ndarray]) –

    Dictionary of parameters used by the waveform.

Source code in qoolqit/waveforms/waveforms.py
def __init__(self, duration: float, area: float) -> None:
"""Initializes a new BlackmanWaveform."""
super().__init__(duration, area=float(area))
duration: float

Returns the duration of the waveform.

params: dict[str, float | ndarray]

Dictionary of parameters used by the waveform.

__rmul__(other: float) -> Waveform (qoolqit.waveforms.base_waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform

Rescale this waveform by a scalar (right-hand multiplication).

Source code in qoolqit/waveforms/base_waveforms.py
def __rmul__(self, other: float) -> Waveform:
"""Rescale this waveform by a scalar (right-hand multiplication)."""
return self.__mul__(other)
__rshift__(other: Waveform (qoolqit.waveforms.base_waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform) -> CompositeWaveform (qoolqit.waveforms.base_waveforms.CompositeWaveform)" href="../waveforms/#qoolqit.waveforms.CompositeWaveform">CompositeWaveform

Returns a new CompositeWaveform composed of this waveform and another.

Source code in qoolqit/waveforms/base_waveforms.py
def __rshift__(self, other: Waveform) -> CompositeWaveform:
"""Returns a new CompositeWaveform composed of this waveform and another."""
if isinstance(other, Waveform):
if isinstance(other, CompositeWaveform):
return CompositeWaveform(self, *other._waveforms)
return CompositeWaveform(self, other)
else:
raise NotImplementedError(f"Composing with object of type {type(other)} not supported.")
ConstantWaveform(duration: float, value: float)

A constant waveform over a given duration.

Parameters:

  • duration (float) –

    the total duration.

  • value (float) –

    the value to take during the duration.

Methods:

  • __rmul__ –

    Rescale this waveform by a scalar (right-hand multiplication).

  • __rshift__ –

    Returns a new CompositeWaveform composed of this waveform and another.

Attributes:

  • duration (float) –

    Returns the duration of the waveform.

  • params (dict[str, float | ndarray]) –

    Dictionary of parameters used by the waveform.

Source code in qoolqit/waveforms/waveforms.py
def __init__(
self,
duration: float,
value: float,
) -> None:
super().__init__(duration, value=float(value))
duration: float

Returns the duration of the waveform.

params: dict[str, float | ndarray]

Dictionary of parameters used by the waveform.

__rmul__(other: float) -> Waveform (qoolqit.waveforms.base_waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform

Rescale this waveform by a scalar (right-hand multiplication).

Source code in qoolqit/waveforms/base_waveforms.py
def __rmul__(self, other: float) -> Waveform:
"""Rescale this waveform by a scalar (right-hand multiplication)."""
return self.__mul__(other)
__rshift__(other: Waveform (qoolqit.waveforms.base_waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform) -> CompositeWaveform (qoolqit.waveforms.base_waveforms.CompositeWaveform)" href="../waveforms/#qoolqit.waveforms.CompositeWaveform">CompositeWaveform

Returns a new CompositeWaveform composed of this waveform and another.

Source code in qoolqit/waveforms/base_waveforms.py
def __rshift__(self, other: Waveform) -> CompositeWaveform:
"""Returns a new CompositeWaveform composed of this waveform and another."""
if isinstance(other, Waveform):
if isinstance(other, CompositeWaveform):
return CompositeWaveform(self, *other._waveforms)
return CompositeWaveform(self, other)
else:
raise NotImplementedError(f"Composing with object of type {type(other)} not supported.")
DelayWaveform(
duration: float, *args: float, **kwargs: float | ndarray
)

An empty waveform.

Parameters:

  • duration (float) –

    the total duration of the waveform.

  • **kwargs (float | ndarray, default: {} ) –

    optional keyword arguments for the waveform function.

Methods:

  • __rmul__ –

    Rescale this waveform by a scalar (right-hand multiplication).

  • __rshift__ –

    Returns a new CompositeWaveform composed of this waveform and another.

Attributes:

  • duration (float) –

    Returns the duration of the waveform.

  • params (dict[str, float | ndarray]) –

    Dictionary of parameters used by the waveform.

Source code in qoolqit/waveforms/base_waveforms.py
def __init__(
self,
duration: float,
*args: float,
**kwargs: float | np.ndarray,
) -> None:
"""Initializes the Waveform.
Args:
duration: the total duration of the waveform.
**kwargs: optional keyword arguments for the waveform function.
"""
if duration <= 0:
raise ValueError("Duration needs to be a positive non-zero value.")
if len(args) > 0:
raise ValueError(
f"Extra arguments in {type(self).__name__} need to be passed as keyword arguments"
)
self._duration = float(duration)
self._params_dict = kwargs
for key, value in kwargs.items():
setattr(self, key, value)
duration: float

Returns the duration of the waveform.

params: dict[str, float | ndarray]

Dictionary of parameters used by the waveform.

__rmul__(other: float) -> Waveform (qoolqit.waveforms.base_waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform

Rescale this waveform by a scalar (right-hand multiplication).

Source code in qoolqit/waveforms/base_waveforms.py
def __rmul__(self, other: float) -> Waveform:
"""Rescale this waveform by a scalar (right-hand multiplication)."""
return self.__mul__(other)
__rshift__(other: Waveform (qoolqit.waveforms.base_waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform) -> CompositeWaveform (qoolqit.waveforms.base_waveforms.CompositeWaveform)" href="../waveforms/#qoolqit.waveforms.CompositeWaveform">CompositeWaveform

Returns a new CompositeWaveform composed of this waveform and another.

Source code in qoolqit/waveforms/base_waveforms.py
def __rshift__(self, other: Waveform) -> CompositeWaveform:
"""Returns a new CompositeWaveform composed of this waveform and another."""
if isinstance(other, Waveform):
if isinstance(other, CompositeWaveform):
return CompositeWaveform(self, *other._waveforms)
return CompositeWaveform(self, other)
else:
raise NotImplementedError(f"Composing with object of type {type(other)} not supported.")
Device(
pulser_device: BaseDevice,
default_converter: Optional[UnitConverter] = None,
)

QoolQit Device wrapper around a Pulser BaseDevice.

Parameters:

  • pulser_device (BaseDevice) –

    a BaseDevice to build the QoolQit device from.

  • default_converter (Optional[UnitConverter], default: None ) –

    optional unit converter to handle unit conversion.

Examples:

From Pulser device:

qoolqit_device = Device(pulser_device=pulser_device)

From remote Pulser device:

from pasqal_cloud import PasqalCloudConnection
from qoolqit import Device
# Fetch the remote device from the connection
connection = PasqalCloudConnection()
pulser_fresnel_device = connection.fetch_available_devices()["FRESNEL"]
# Wrap a Pulser device object into a QoolQit Device
fresnel_device = Device(pulser_device=PulserFresnelDevice)

From custom Pulser device:

from dataclasses import replace
from pulser import AnalogDevice
from qoolqit import Device
# Converting the pulser Device object in a VirtualDevice object
VirtualAnalog = AnalogDevice.to_virtual()
# Replacing desired values
ModdedAnalogDevice = replace(
VirtualAnalog,
max_radial_distance=100,
max_sequence_duration=7000
)
# Wrap a Pulser device object into a QoolQit Device
mod_analog_device = Device(pulser_device=ModdedAnalogDevice)

Methods:

  • from_connection –

    Return the specified device from the selected device from a connection.

  • info –

    Show the device short description and constraints.

  • reset_converter –

    Resets the unit converter to the default one.

  • set_distance_unit –

    Changes the unit converter according to a reference distance unit.

  • set_energy_unit –

    Changes the unit converter according to a reference energy unit.

Attributes:

  • specs (dict[str, float | None]) –

    Return the device specification constraints.

Source code in qoolqit/devices/device.py
def __init__(
self,
pulser_device: BaseDevice,
default_converter: Optional[UnitConverter] = None,
) -> None:
if not isinstance(pulser_device, BaseDevice):
raise TypeError("`pulser_device` must be an instance of Pulser BaseDevice class.")
# Store it for all subsequent lookups
self._pulser_device: BaseDevice = pulser_device
self._name: str = self._pulser_device.name
# Physical constants / channel & limit lookups (assumes 'rydberg_global' channel)
self._C6 = self._pulser_device.interaction_coeff
self._clock_period = self._pulser_device.channels["rydberg_global"].clock_period
# Relevant limits from the underlying device (float or None)
self._max_duration = self._pulser_device.max_sequence_duration
self._max_amp = self._pulser_device.channels["rydberg_global"].max_amp
self._upper_amp = self._max_amp or 4 * math.pi
self._max_abs_det = self._pulser_device.channels["rydberg_global"].max_abs_detuning
self._min_distance = self._pulser_device.min_atom_distance
self._lower_distance = self._min_distance or 5.0
self._max_radial_distance = self._pulser_device.max_radial_distance
# ratio between maximum amplitude and maximum interaction energy J_max = C6/r_min^6
self._energy_ratio: float = (self._upper_amp * self._lower_distance**6) / self._C6
# layouts
self._requires_layout = self._pulser_device.requires_layout
if default_converter is not None:
# Snapshot the caller-provided factors so reset() reproduces them exactly.
t0, e0, d0 = default_converter.factors
self._default_factory: Callable[[], UnitConverter] = lambda: UnitConverter(
self._C6, t0, e0, d0
)
else:
self._default_factory = lambda: UnitConverter.from_distance(
self._C6, self._lower_distance
)
self.reset_converter()
specs: dict[str, float | None]

Return the device specification constraints.

from_connection(
connection: RemoteConnection, name: str
) -> Device (qoolqit.devices.device.Device)" href="#qoolqit.Device">Device

Return the specified device from the selected device from a connection.

Available devices through the provided connection are can be seen with the connection.fetch_available_devices() method.

Parameters:

  • connection (RemoteConnection) –

    connection object to fetch the available devices.

  • name (str) –

    The name of the desired device.

Returns:

  • Device ( Device ) –

    The requested device.

Raises:

  • ValueError –

    If the requested device is not available through the provided connection.

Example:

from pasqal_cloud import PasqalCloudConnection
fresnel_device = Device.from_connection(connection=PasqalCloudConnection(), name="FRESNEL")
Source code in qoolqit/devices/device.py
@classmethod
def from_connection(cls, connection: RemoteConnection, name: str) -> Device:
"""Return the specified device from the selected device from a connection.
Available devices through the provided connection are can be seen with
the `connection.fetch_available_devices()` method.
Args:
connection (RemoteConnection): connection object to fetch the available devices.
name (str): The name of the desired device.
Returns:
Device: The requested device.
Raises:
ValueError: If the requested device is not available through the provided connection.
Example:
```python
from pasqal_cloud import PasqalCloudConnection
fresnel_device = Device.from_connection(connection=PasqalCloudConnection(), name="FRESNEL")
```
"""
available_remote_devices = connection.fetch_available_devices()
if name not in available_remote_devices:
raise ValueError(f"Device {name} is not available through the provided connection.")
pulser_device = available_remote_devices[name]
return cls(pulser_device=pulser_device)
info() -> None

Show the device short description and constraints.

Source code in qoolqit/devices/device.py
def info(self) -> None:
"""Show the device short description and constraints."""
print(self)
reset_converter() -> None

Resets the unit converter to the default one.

Source code in qoolqit/devices/device.py
def reset_converter(self) -> None:
"""Resets the unit converter to the default one."""
# Create a NEW converter so mutations don't persist.
self._converter = self._default_converter
set_distance_unit(distance: float) -> None

Changes the unit converter according to a reference distance unit.

Source code in qoolqit/devices/device.py
def set_distance_unit(self, distance: float) -> None:
"""Changes the unit converter according to a reference distance unit."""
self.converter.factors = self.converter.factors_from_distance(distance)
set_energy_unit(energy: float) -> None

Changes the unit converter according to a reference energy unit.

Source code in qoolqit/devices/device.py
def set_energy_unit(self, energy: float) -> None:
"""Changes the unit converter according to a reference energy unit."""
self.converter.factors = self.converter.factors_from_energy(energy)
DigitalAnalogDevice()

A device with digital and analog capabilities.

Methods:

  • from_connection –

    Return the specified device from the selected device from a connection.

  • info –

    Show the device short description and constraints.

  • reset_converter –

    Resets the unit converter to the default one.

  • set_distance_unit –

    Changes the unit converter according to a reference distance unit.

  • set_energy_unit –

    Changes the unit converter according to a reference energy unit.

Attributes:

  • specs (dict[str, float | None]) –

    Return the device specification constraints.

Source code in qoolqit/devices/device.py
def __init__(self) -> None:
super().__init__(pulser_device=pulser.DigitalAnalogDevice)
specs: dict[str, float | None]

Return the device specification constraints.

from_connection(
connection: RemoteConnection, name: str
) -> Device (qoolqit.devices.device.Device)" href="#qoolqit.Device">Device

Return the specified device from the selected device from a connection.

Available devices through the provided connection are can be seen with the connection.fetch_available_devices() method.

Parameters:

  • connection (RemoteConnection) –

    connection object to fetch the available devices.

  • name (str) –

    The name of the desired device.

Returns:

  • Device ( Device ) –

    The requested device.

Raises:

  • ValueError –

    If the requested device is not available through the provided connection.

Example:

from pasqal_cloud import PasqalCloudConnection
fresnel_device = Device.from_connection(connection=PasqalCloudConnection(), name="FRESNEL")
Source code in qoolqit/devices/device.py
@classmethod
def from_connection(cls, connection: RemoteConnection, name: str) -> Device:
"""Return the specified device from the selected device from a connection.
Available devices through the provided connection are can be seen with
the `connection.fetch_available_devices()` method.
Args:
connection (RemoteConnection): connection object to fetch the available devices.
name (str): The name of the desired device.
Returns:
Device: The requested device.
Raises:
ValueError: If the requested device is not available through the provided connection.
Example:
```python
from pasqal_cloud import PasqalCloudConnection
fresnel_device = Device.from_connection(connection=PasqalCloudConnection(), name="FRESNEL")
```
"""
available_remote_devices = connection.fetch_available_devices()
if name not in available_remote_devices:
raise ValueError(f"Device {name} is not available through the provided connection.")
pulser_device = available_remote_devices[name]
return cls(pulser_device=pulser_device)
info() -> None

Show the device short description and constraints.

Source code in qoolqit/devices/device.py
def info(self) -> None:
"""Show the device short description and constraints."""
print(self)
reset_converter() -> None

Resets the unit converter to the default one.

Source code in qoolqit/devices/device.py
def reset_converter(self) -> None:
"""Resets the unit converter to the default one."""
# Create a NEW converter so mutations don't persist.
self._converter = self._default_converter
set_distance_unit(distance: float) -> None

Changes the unit converter according to a reference distance unit.

Source code in qoolqit/devices/device.py
def set_distance_unit(self, distance: float) -> None:
"""Changes the unit converter according to a reference distance unit."""
self.converter.factors = self.converter.factors_from_distance(distance)
set_energy_unit(energy: float) -> None

Changes the unit converter according to a reference energy unit.

Source code in qoolqit/devices/device.py
def set_energy_unit(self, energy: float) -> None:
"""Changes the unit converter according to a reference energy unit."""
self.converter.factors = self.converter.factors_from_energy(energy)
Drive(
*,
amplitude: Waveform (qoolqit.waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform,
detuning: Waveform (qoolqit.waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform | None = None,
dmm: DetuningMapModulator
dataclass
(qoolqit.drive.DetuningMapModulator)" href="../drive/#qoolqit.drive.DetuningMapModulator">DetuningMapModulator | None = None,
phase: float = 0.0,
)

The drive Hamiltonian acting over a duration.

The Drive specifies the control parameters for the time-dependent drive Hamiltonian in the Rydberg model (see https://docs.pasqal.com/qoolqit/get_started/qoolqit_model/ (external) for details),

H_drive(t) = Σᵢ [Ω(t)/2 (cos φ(t) σˣᵢ - sin φ(t) σʸᵢ)] - Σᵢ [δ(t) + εᵢ Δ(t)] nᵢ

representing: - Amplitude Ω(t): Controls the Rabi frequency that drives qubits. - Detuning δ(t): Controls the energy offset of the Rydberg state. - dmm εᵢ, Δ(t): Detuning Map Modulator (DMM) for additional qubit-specific detunings. - Phase φ: Global phase applied to the amplitude term.

Parameters:

  • amplitude (Waveform) –

    Time-dependent amplitude waveform Ω(t) representing the Rabi frequency. Controls the strength of the coupling between ground and Rydberg states. Must be positive for all times.

  • detuning (Waveform | None, default: None ) –

    Time-dependent detuning waveform δ(t) representing the energy offset of the Rydberg state relative to resonance. If None, defaults to zero detuning (Delay waveform) for the duration of the amplitude.

  • dmm (DetuningMapModulator | None, default: None ) –

    DetuningMapModulator instance for additional negative detuning waveform Δ(t) ≤ 0 applied to individual qubits as specified by its weights attribute εᵢ.

  • phase (float, default: 0.0 ) –

    Global phase φ applied to the amplitude term in the Hamiltonian. Defaults to 0.0 (no phase).

Raises:

  • TypeError –

    If amplitude or detuning are not Waveform instances.

  • ValueError –

    If the amplitude waveform has negative values.

Note
  • All arguments must be passed as keyword arguments.
  • If amplitude and detuning have different durations, the shorter one is automatically extended with a Delay to match the longer duration.
  • DetuningMapModulator waveform must be negative for all times (≤ 0) as it represents energy shifts below the resonance.
Example

from qoolqit import Drive from qoolqit.waveforms import ConstantWaveform, RampWaveform

drive = Drive(amplitude=ConstantWaveform(10.0, 1.5))

Drive with time-varying amplitude and detuning

Section titled “Drive with time-varying amplitude and detuning”

amp = RampWaveform(5.0, 0.0, 2.0) det = ConstantWaveform(5.0, -1.0) drive = Drive(amplitude=amp, detuning=det, phase=0.5)

Attributes:

Source code in qoolqit/drive.py
def __init__(
self,
*,
amplitude: Waveform,
detuning: Waveform | None = None,
dmm: DetuningMapModulator | None = None,
phase: float = 0.0,
) -> None:
"""Initialize a Drive.
The Drive specifies the control parameters for the time-dependent drive Hamiltonian
in the Rydberg model
(see https://docs.pasqal.com/qoolqit/get_started/qoolqit_model/ for details),
H_drive(t) = Σᵢ [Ω(t)/2 (cos φ(t) σˣᵢ - sin φ(t) σʸᵢ)] - Σᵢ [δ(t) + εᵢ Δ(t)] nᵢ
representing:
- Amplitude Ω(t): Controls the Rabi frequency that drives qubits.
- Detuning δ(t): Controls the energy offset of the Rydberg state.
- dmm εᵢ, Δ(t): Detuning Map Modulator (DMM) for additional qubit-specific detunings.
- Phase φ: Global phase applied to the amplitude term.
Args:
amplitude: Time-dependent amplitude waveform Ω(t) representing the Rabi frequency.
Controls the strength of the coupling between ground and Rydberg states.
Must be positive for all times.
detuning: Time-dependent detuning waveform δ(t) representing the energy offset
of the Rydberg state relative to resonance. If None, defaults to zero
detuning (Delay waveform) for the duration of the amplitude.
dmm: DetuningMapModulator instance for additional negative detuning waveform Δ(t) ≤ 0
applied to individual qubits as specified by its `weights` attribute εᵢ.
phase: Global phase φ applied to the amplitude term in the Hamiltonian.
Defaults to 0.0 (no phase).
Raises:
TypeError: If amplitude or detuning are not Waveform instances.
ValueError: If the amplitude waveform has negative values.
Note:
- All arguments must be passed as keyword arguments.
- If amplitude and detuning have different durations, the shorter one is
automatically extended with a Delay to match the longer duration.
- DetuningMapModulator waveform must be negative for all times
(≤ 0) as it represents energy shifts below the resonance.
Example:
>>> from qoolqit import Drive
>>> from qoolqit.waveforms import ConstantWaveform, RampWaveform
>>>
>>> # Simple constant drive
>>> drive = Drive(amplitude=ConstantWaveform(10.0, 1.5))
>>>
>>> # Drive with time-varying amplitude and detuning
>>> amp = RampWaveform(5.0, 0.0, 2.0)
>>> det = ConstantWaveform(5.0, -1.0)
>>> drive = Drive(amplitude=amp, detuning=det, phase=0.5)
"""
for arg in [amplitude, detuning]:
if arg is not None and not isinstance(arg, Waveform):
raise TypeError("'amplitude' and 'detuning' must be of type Waveform.")
if amplitude.min() < 0.0:
raise ValueError("'amplitude' must be positive.")
self._amplitude = amplitude
self._detuning = detuning if detuning is not None else DelayWaveform(amplitude.duration)
self._amplitude_orig = self._amplitude
self._detuning_orig = self._detuning
# adjust amplitude and detuning waveforms to match the duration
if self._amplitude.duration > self._detuning.duration:
extra_duration = self._amplitude.duration - self._detuning.duration
self._detuning = CompositeWaveform(self._detuning, DelayWaveform(extra_duration))
elif self._detuning.duration > self._amplitude.duration:
extra_duration = self._detuning.duration - self._amplitude.duration
self._amplitude = CompositeWaveform(self._amplitude, DelayWaveform(extra_duration))
self._duration = self._amplitude.duration
if dmm is not None and not isinstance(dmm, DetuningMapModulator):
raise TypeError("'dmm' must be of type DetuningMapModulator.")
self._dmm = dmm
self._phase = phase
amplitude: Waveform (qoolqit.waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform

The amplitude waveform in the drive.

detuning: Waveform (qoolqit.waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform

The detuning waveform in the drive.

dmm: DetuningMapModulator
dataclass
(qoolqit.drive.DetuningMapModulator)" href="../drive/#qoolqit.drive.DetuningMapModulator">DetuningMapModulator | None

Detuning Map Modulator (DMM) applied to individual qubits.

phase: float

The phase value in the drive.

InterpolatedWaveform(
duration: float,
values: ArrayLike,
times: ArrayLike | None = None,
)

A waveform created from shape-preserving interpolation of data points.

This class creates a smooth waveform by interpolating between specified data points using PCHIP (Piecewise Cubic Hermite Interpolating Polynomial) interpolation. The interpolating curve preserves the shape of the input data: bounds (avoiding under/overshooting), monotonicity, and convexity.

Uses scipy's PchipInterpolator for the interpolation.

Attributes:

  • duration (float) –

    The waveform duration.

  • values (float) –

    Array-like sequence of waveform values at the interpolation points. Must be convertible to float. These values define the amplitude of the waveform at the corresponding time points.

  • times (float) –

    Optional array-like sequence of fractional times in the range [0, 1] indicating where to place each value on the time axis. Must have the same length as values. If not provided, values are distributed evenly across the waveform duration. Default is None.

ValueError: If times contains values outside [0, 1] or if times and values have different lengths.

Example

Create a waveform with 4 points over 100ns

Section titled “Create a waveform with 4 points over 100ns”

values = [0.0, 1.0, 0.5, 0.0] wf = InterpolatedWaveform(100, values)

times = [0.0, 0.2, 0.8, 1.0] # Non-uniform spacing wf = InterpolatedWaveform(100, values, times)

Parameters:

  • duration (float) –

    The total duration of the waveform. Must be positive.

  • values (ArrayLike) –

    Array-like sequence of waveform values at interpolation points. Can be a list, tuple, numpy array, or any sequence convertible to float.

  • times (ArrayLike | None, default: None ) –

    Optional array-like sequence of fractional times in [0, 1]. If provided, must have the same length as values. If None, values are evenly spaced across the duration. Default is None.

Raises:

  • ValueError –

    If any value in times is outside [0, 1], or if times and values have different lengths.

Methods:

  • __rmul__ –

    Rescale this waveform by a scalar (right-hand multiplication).

  • __rshift__ –

    Returns a new CompositeWaveform composed of this waveform and another.

Source code in qoolqit/waveforms/waveforms.py
def __init__(
self,
duration: float,
values: ArrayLike,
times: ArrayLike | None = None,
):
"""Initialize an Interpolated waveform.
Args:
duration: The total duration of the waveform. Must be positive.
values: Array-like sequence of waveform values at interpolation points.
Can be a list, tuple, numpy array, or any sequence convertible to float.
times: Optional array-like sequence of fractional times in [0, 1]. If provided,
must have the same length as `values`. If None, values are evenly spaced
across the duration. Default is None.
Raises:
ValueError: If any value in `times` is outside [0, 1], or if `times` and
`values` have different lengths.
"""
super().__init__(duration)
self._values = np.array(values, dtype=float)
if times is not None:
self._times = np.array(times, dtype=float)
if any([(ft < 0) or (ft > 1) for ft in self._times]):
raise ValueError("All values in `times` must be in [0,1].")
if len(self._times) != len(self._values):
raise ValueError(
"Arguments `values` and `times` must be arrays of the same length."
)
else:
self._times = np.linspace(0, 1, num=len(self._values))
self._interp_func = PchipInterpolator(duration * self._times, values)
duration: float

Returns the duration of the waveform.

params: dict[str, float | ndarray]

Dictionary of parameters used by the waveform.

__rmul__(other: float) -> Waveform (qoolqit.waveforms.base_waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform

Rescale this waveform by a scalar (right-hand multiplication).

Source code in qoolqit/waveforms/base_waveforms.py
def __rmul__(self, other: float) -> Waveform:
"""Rescale this waveform by a scalar (right-hand multiplication)."""
return self.__mul__(other)
__rshift__(other: Waveform (qoolqit.waveforms.base_waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform) -> CompositeWaveform (qoolqit.waveforms.base_waveforms.CompositeWaveform)" href="../waveforms/#qoolqit.waveforms.CompositeWaveform">CompositeWaveform

Returns a new CompositeWaveform composed of this waveform and another.

Source code in qoolqit/waveforms/base_waveforms.py
def __rshift__(self, other: Waveform) -> CompositeWaveform:
"""Returns a new CompositeWaveform composed of this waveform and another."""
if isinstance(other, Waveform):
if isinstance(other, CompositeWaveform):
return CompositeWaveform(self, *other._waveforms)
return CompositeWaveform(self, other)
else:
raise NotImplementedError(f"Composing with object of type {type(other)} not supported.")
MockDevice()

A virtual device for unconstrained prototyping.

Methods:

  • from_connection –

    Return the specified device from the selected device from a connection.

  • info –

    Show the device short description and constraints.

  • reset_converter –

    Resets the unit converter to the default one.

  • set_distance_unit –

    Changes the unit converter according to a reference distance unit.

  • set_energy_unit –

    Changes the unit converter according to a reference energy unit.

Attributes:

  • specs (dict[str, float | None]) –

    Return the device specification constraints.

Source code in qoolqit/devices/device.py
def __init__(self) -> None:
super().__init__(pulser_device=pulser.MockDevice)
specs: dict[str, float | None]

Return the device specification constraints.

from_connection(
connection: RemoteConnection, name: str
) -> Device (qoolqit.devices.device.Device)" href="#qoolqit.Device">Device

Return the specified device from the selected device from a connection.

Available devices through the provided connection are can be seen with the connection.fetch_available_devices() method.

Parameters:

  • connection (RemoteConnection) –

    connection object to fetch the available devices.

  • name (str) –

    The name of the desired device.

Returns:

  • Device ( Device ) –

    The requested device.

Raises:

  • ValueError –

    If the requested device is not available through the provided connection.

Example:

from pasqal_cloud import PasqalCloudConnection
fresnel_device = Device.from_connection(connection=PasqalCloudConnection(), name="FRESNEL")
Source code in qoolqit/devices/device.py
@classmethod
def from_connection(cls, connection: RemoteConnection, name: str) -> Device:
"""Return the specified device from the selected device from a connection.
Available devices through the provided connection are can be seen with
the `connection.fetch_available_devices()` method.
Args:
connection (RemoteConnection): connection object to fetch the available devices.
name (str): The name of the desired device.
Returns:
Device: The requested device.
Raises:
ValueError: If the requested device is not available through the provided connection.
Example:
```python
from pasqal_cloud import PasqalCloudConnection
fresnel_device = Device.from_connection(connection=PasqalCloudConnection(), name="FRESNEL")
```
"""
available_remote_devices = connection.fetch_available_devices()
if name not in available_remote_devices:
raise ValueError(f"Device {name} is not available through the provided connection.")
pulser_device = available_remote_devices[name]
return cls(pulser_device=pulser_device)
info() -> None

Show the device short description and constraints.

Source code in qoolqit/devices/device.py
def info(self) -> None:
"""Show the device short description and constraints."""
print(self)
reset_converter() -> None

Resets the unit converter to the default one.

Source code in qoolqit/devices/device.py
def reset_converter(self) -> None:
"""Resets the unit converter to the default one."""
# Create a NEW converter so mutations don't persist.
self._converter = self._default_converter
set_distance_unit(distance: float) -> None

Changes the unit converter according to a reference distance unit.

Source code in qoolqit/devices/device.py
def set_distance_unit(self, distance: float) -> None:
"""Changes the unit converter according to a reference distance unit."""
self.converter.factors = self.converter.factors_from_distance(distance)
set_energy_unit(energy: float) -> None

Changes the unit converter according to a reference energy unit.

Source code in qoolqit/devices/device.py
def set_energy_unit(self, energy: float) -> None:
"""Changes the unit converter according to a reference energy unit."""
self.converter.factors = self.converter.factors_from_energy(energy)
PiecewiseLinearWaveform(
durations: list[float] | tuple[float, ...] | ndarray,
values: list[float] | tuple[float, ...] | ndarray,
)

A piecewise linear waveform.

Creates a composite waveform of N ramps that linearly interpolate through the given N+1 values.

Parameters:

  • durations (list[float] | tuple[float, ...] | ndarray) –

    list or tuple of N duration values.

  • values (list[float] | tuple[float, ...] | ndarray) –

    list or tuple of N+1 waveform values.

Methods:

  • __rmul__ –

    Rescale this waveform by a scalar (right-hand multiplication).

  • max –

    Get the maximum value of the waveform.

  • min –

    Get the minimum value of the waveform.

Attributes:

  • duration (float) –

    Returns the duration of the waveform.

  • durations (list[float]) –

    Returns the list of durations of each individual waveform.

  • n_waveforms (int) –

    Returns the number of waveforms.

  • params (dict[str, float | ndarray]) –

    Dictionary of parameters used by the waveform.

  • times (list[float]) –

    Returns the list of times when each individual waveform starts.

  • waveforms (list[Waveform]) –

    Returns a list of the individual waveforms.

Source code in qoolqit/waveforms/waveforms.py
def __init__(
self,
durations: list[float] | tuple[float, ...] | np.ndarray,
values: list[float] | tuple[float, ...] | np.ndarray,
) -> None:
if len(durations) + 1 != len(values) or len(durations) == 1:
raise ValueError(
"A PiecewiseLinearWaveform requires N durations and N + 1 values, for N >= 2."
)
for duration in durations:
if duration == 0.0:
raise ValueError("A PiecewiseLinearWaveform interval cannot have zero duration.")
# Stored as-is (not cast to float): unlike the per-segment RampWaveforms below,
# this attribute can retain an int dtype if `values` is int-typed.
self.values = values
wfs = [RampWaveform(dur, values[i], values[i + 1]) for i, dur in enumerate(durations)]
super().__init__(*wfs)
duration: float

Returns the duration of the waveform.

durations: list[float]

Returns the list of durations of each individual waveform.

n_waveforms: int

Returns the number of waveforms.

params: dict[str, float | ndarray]

Dictionary of parameters used by the waveform.

times: list[float]

Returns the list of times when each individual waveform starts.

waveforms: list[ Waveform (qoolqit.waveforms.base_waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform]

Returns a list of the individual waveforms.

__rmul__(other: float) -> Waveform (qoolqit.waveforms.base_waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform

Rescale this waveform by a scalar (right-hand multiplication).

Source code in qoolqit/waveforms/base_waveforms.py
def __rmul__(self, other: float) -> Waveform:
"""Rescale this waveform by a scalar (right-hand multiplication)."""
return self.__mul__(other)
max() -> float

Get the maximum value of the waveform.

Source code in qoolqit/waveforms/base_waveforms.py
def max(self) -> float:
"""Get the maximum value of the waveform."""
return max([wf.max() for wf in self.waveforms])
min() -> float

Get the minimum value of the waveform.

Source code in qoolqit/waveforms/base_waveforms.py
def min(self) -> float:
"""Get the minimum value of the waveform."""
return min([wf.min() for wf in self.waveforms])
QuantumProgram(register: Register (qoolqit.register.Register)" href="../register/#qoolqit.register.Register">Register, drive: Drive (qoolqit.drive.Drive)" href="../drive/#qoolqit.drive.Drive">Drive)

A program representing a Sequence acting on a Register of qubits.

Parameters:

  • register (Register) –

    the register of qubits, defining their positions.

  • drive (Drive) –

    the drive acting on qubits, defining amplitude, detuning and phase.

Methods:

  • compile_to –

    Compiles the quantum program for execution on a specific device.

Attributes:

Source code in qoolqit/program.py
def __init__(
self,
register: Register,
drive: Drive,
) -> None:
if not isinstance(register, Register):
raise TypeError("`register` must be of type Register.")
self._register = register
if not isinstance(drive, Drive):
raise TypeError("`drive` must be of type Drive.")
if drive.dmm is not None:
dmm_weights = drive.dmm.weights
for qid in dmm_weights.keys():
if qid not in register.qubits:
raise ValueError(
"In this QuantumProgram, the drive's detuning modulator map (DMM) "
f"and the register do not match: qubit {qid} appears in the DMM "
"but is not defined in the register."
)
self._drive = drive
self._compiled_sequence: PulserSequence | None = None
compiled_sequence: Sequence

The Pulser sequence compiled to a specific device.

drive: Drive (qoolqit.drive.Drive)" href="../drive/#qoolqit.drive.Drive">Drive

The driving waveforms.

is_compiled: bool

Check if the program has been compiled.

register: Register (qoolqit.register.Register)" href="../register/#qoolqit.register.Register">Register

The register of qubits.

compile_to(
device: Device (qoolqit.devices.Device)" href="../devices/#qoolqit.devices.Device">Device,
profile: Literal["default", "max_energy"]
| CompilerProfile = DEFAULT,
device_max_duration_ratio: float | None = None,
) -> None

Compiles the quantum program for execution on a specific device.

The compilation process translates a program to make it runnable on a specific device:

  • Dimensionalization: Rescale the drive amplitude and the register positions to physical units compatible with the device.
  • Translation: Translate the program to a lower-level representation (Pulser) that can be executed on the device.

There are two compilation profiles:

  • "default": Compile the program as it is. The drive and the register positions must respect the hardware constraints of the device which can be inspected using device.specs(). The CompilerProfile.WORKING_POINT is deprecated aliases for this profile.
  • "max_energy": Scale the program to utilize the device's maximum capabilities. The drive amplitude and the register positions are rescaled to achieve respectively the maximum amplitude and the minimum pairwise distance compatible with the input program and the device's constraints.

The following option does NOT preserve the input program, but rather adapts the program to the device's constraints. Programs compiled this way are not portable across devices.

  • device_max_duration_ratio: Rescale the drive duration to a fraction of the device's maximum allowed duration. Useful in adiabatic protocols where one simply seeks to minimize the time derivative of the drive's amplitude.

Parameters:

  • device (Device) –

    The target device for compilation. Must be a QoolQit Device.

  • profile (Literal['default', 'max_energy'] | CompilerProfile, default: DEFAULT ) –

    The compilation profile used to translate the program. Defaults to CompilerProfile.DEFAULT.

  • device_max_duration_ratio (float | None, default: None ) –

    The fraction of the device's maximum allowed duration to set the program duration to, or None to leave it unset. Must be a number in the range (0, 1]. Can only be set if the device has a maximum allowed duration.

Raises:

  • TypeError –

    If device is not a QoolQit Device.

  • ValueError –

    If device_max_duration_ratio is set but the device has no maximum allowed duration, or if it is not in the range (0, 1].

  • CompilationError –

    If the compilation fails due to device constraints.

Source code in qoolqit/program.py
def compile_to(
self,
device: Device,
profile: Literal["default", "max_energy"] | CompilerProfile = CompilerProfile.DEFAULT,
device_max_duration_ratio: float | None = None,
) -> None:
"""Compiles the quantum program for execution on a specific device.
The compilation process translates a program to make it runnable on a specific device:
- Dimensionalization: Rescale the drive amplitude and the register positions to
physical units compatible with the device.
- Translation: Translate the program to a lower-level representation (Pulser) that
can be executed on the device.
There are two compilation profiles:
- "default": Compile the program as it is. The drive and the register positions
must respect the hardware constraints of the device which can be inspected
using `device.specs()`. The `CompilerProfile.WORKING_POINT` is deprecated
aliases for this profile.
- "max_energy": Scale the program to utilize the device's
maximum capabilities. The drive amplitude and the register positions are rescaled
to achieve respectively the maximum amplitude and the minimum pairwise distance
compatible with the input program and the device's constraints.
The following option does NOT preserve the input program, but rather adapts the program
to the device's constraints. Programs compiled this way are not portable across devices.
- device_max_duration_ratio: Rescale the drive duration to a fraction of the
device's maximum allowed duration. Useful in adiabatic protocols where one simply
seeks to minimize the time derivative of the drive's amplitude.
Args:
device: The target device for compilation. Must be a QoolQit Device.
profile: The compilation profile used to translate the program.
Defaults to CompilerProfile.DEFAULT.
device_max_duration_ratio: The fraction of the device's maximum allowed duration
to set the program duration to, or None to leave it unset. Must be a number
in the range (0, 1]. Can only be set if the device has a maximum allowed
duration.
Raises:
TypeError: If `device` is not a QoolQit Device.
ValueError: If `device_max_duration_ratio` is set but the device has no maximum
allowed duration, or if it is not in the range (0, 1].
CompilationError: If the compilation fails due to device constraints.
"""
if not isinstance(device, Device):
raise TypeError("`device` must be of type `qoolqit.devices.Device`.")
if device_max_duration_ratio is not None:
if device._max_duration is None:
raise ValueError(
"Cannot set `device_max_duration_ratio` because the target device "
"does not have a maximum allowed duration."
)
if not (0 < device_max_duration_ratio <= 1):
raise ValueError(
"`device_max_duration_ratio` must be between 0 and 1, "
f"got {device_max_duration_ratio} instead."
)
# Check if device supports DMM and has a DMM channel
if self.drive.dmm is not None:
if not device._device.dmm_channels:
raise CompilationError(
"The device does not support DMM. Please use a device that supports DMM."
)
profile = CompilerProfile(profile)
compiler = SequenceCompiler(
self.register, self.drive, device, profile, device_max_duration_ratio
)
self._device = device
self._compiled_sequence = compiler.compile_sequence()
RampWaveform(
duration: float,
initial_value: float,
final_value: float,
)

A ramp that linearly interpolates between an initial and final value.

Parameters:

  • duration (float) –

    the total duration.

  • initial_value (float) –

    the initial value at t = 0.

  • final_value (float) –

    the final value at t = duration.

Methods:

  • __rmul__ –

    Rescale this waveform by a scalar (right-hand multiplication).

  • __rshift__ –

    Returns a new CompositeWaveform composed of this waveform and another.

Attributes:

  • duration (float) –

    Returns the duration of the waveform.

  • params (dict[str, float | ndarray]) –

    Dictionary of parameters used by the waveform.

Source code in qoolqit/waveforms/waveforms.py
def __init__(
self,
duration: float,
initial_value: float,
final_value: float,
) -> None:
super().__init__(
duration, initial_value=float(initial_value), final_value=float(final_value)
)
duration: float

Returns the duration of the waveform.

params: dict[str, float | ndarray]

Dictionary of parameters used by the waveform.

__rmul__(other: float) -> Waveform (qoolqit.waveforms.base_waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform

Rescale this waveform by a scalar (right-hand multiplication).

Source code in qoolqit/waveforms/base_waveforms.py
def __rmul__(self, other: float) -> Waveform:
"""Rescale this waveform by a scalar (right-hand multiplication)."""
return self.__mul__(other)
__rshift__(other: Waveform (qoolqit.waveforms.base_waveforms.Waveform)" href="../waveforms/#qoolqit.waveforms.Waveform">Waveform) -> CompositeWaveform (qoolqit.waveforms.base_waveforms.CompositeWaveform)" href="../waveforms/#qoolqit.waveforms.CompositeWaveform">CompositeWaveform

Returns a new CompositeWaveform composed of this waveform and another.

Source code in qoolqit/waveforms/base_waveforms.py
def __rshift__(self, other: Waveform) -> CompositeWaveform:
"""Returns a new CompositeWaveform composed of this waveform and another."""
if isinstance(other, Waveform):
if isinstance(other, CompositeWaveform):
return CompositeWaveform(self, *other._waveforms)
return CompositeWaveform(self, other)
else:
raise NotImplementedError(f"Composing with object of type {type(other)} not supported.")
Register(
qubits: Mapping[
str, Sequence[float] | NDArray[float64] | Tensor
]
| Mapping[
int, Sequence[float] | NDArray[float64] | Tensor
],
)

A QoolQit register mapping qubit IDs to 2D coordinates.

Examples:

From a dictionary of qubit IDs and coordinates:

>>> reg = Register({"a": (0.0, 0.0), "b": (1.0, 0.0), "c": (0.0, 1.0)})
>>> reg = Register({0: (0.0, 0.0), 1: (1.0, 0.0), 2: (0.0, 1.0)})

From a list of coordinates (qubit IDs are assigned automatically as strings "0", "1", ...):

>>> reg = Register.from_coordinates([(0.0, 0.0), (1.0, 0.0), (0.0, 1.0)])

Using numpy arrays as coordinates:

>>> import numpy as np
>>> reg = Register({"a": np.array([0.0, 0.0]), "b": np.array([1.0, 0.0])})

Using torch tensors as coordinates:

>>> import torch
>>> reg = Register({"a": torch.tensor([0.0, 0.0]), "b": torch.tensor([1.0, 0.0])})

Parameters:

  • qubits (Mapping[str, Sequence[float] | NDArray[float64] | Tensor] | Mapping[int, Sequence[float] | NDArray[float64] | Tensor]) –

    a dictionary of qubits and respective 2D coordinates {q: (x, y), ...}. Each coordinate must be castable to a numpy or torch array of shape (2,).

Raises:

  • TypeError –

    If qubits is not a Mapping.

  • ValueError –

    If qubits dictionary is empty.

  • ValueError –

    If a qubit coordinate cannot be converted to an array of floats, or if the converted coordinate is not a point in 2D.

Methods:

  • circle –

    Initializes a Register with qubits arranged in a circle.

  • distances –

    Distance between each qubit pair.

  • draw –

    Draw the register.

  • from_coordinates –

    Initializes a Register from a sequence or array of coordinates.

  • from_graph –

    Initializes a Register from a graph that has coordinates.

  • interaction_matrix –

    Interaction 1/r^6 between each qubit pair, as a matrix (0 on the diagonal).

  • interactions –

    Interaction 1/r^6 between each qubit pair.

  • line –

    Initializes a Register with qubits arranged in a line.

  • max_radial_distance –

    Maximum radial distance between all qubits.

  • min_distance –

    Minimum distance between all qubit pairs.

  • radial_distances –

    Radial distance of each qubit from the origin.

  • rectangular –

    Initializes a rectangular Register of qubits.

  • square –

    Initializes a square Register of qubits.

  • triangular –

    Initializes a triangular lattice Register of qubits.

Attributes:

  • n_qubits (int) –

    Number of qubits in the Register.

  • qubits (dict) –

    Returns a dictionary of qubits and respective coordinates.

  • qubits_ids (tuple[str | int, ...]) –

    Returns the qubit IDs.

Source code in qoolqit/register.py
def __init__(
self,
qubits: (
Mapping[str, Sequence[float] | npt.NDArray[np.float64] | torch.Tensor]
| Mapping[int, Sequence[float] | npt.NDArray[np.float64] | torch.Tensor]
),
) -> None:
"""Default constructor for the Register.
Args:
qubits: a dictionary of qubits and respective 2D coordinates {q: (x, y), ...}.
Each coordinate must be castable to a numpy or torch array of shape (2,).
Raises:
TypeError: If `qubits` is not a Mapping.
ValueError: If `qubits` dictionary is empty.
ValueError: If a qubit coordinate cannot be converted to an array of
floats, or if the converted coordinate is not a point in 2D.
"""
if not isinstance(qubits, Mapping):
raise TypeError("`qubits` must be a Mapping of qubit ids to coordinates.")
if not qubits:
raise ValueError("Register cannot be empty.")
self._qubits_ids: tuple[str | int, ...] = tuple(qubits.keys())
validated_coords = [self._validate_coord(k, c) for k, c in qubits.items()]
self._coords = self._stack_coords(validated_coords)
n_qubits: int

Number of qubits in the Register.

qubits: dict

Returns a dictionary of qubits and respective coordinates.

qubits_ids: tuple[str | int, ...]

Returns the qubit IDs.

circle(n: int, spacing: float = 1.0) -> Register (qoolqit.register.Register)" href="../register/#qoolqit.register.Register">Register

Initializes a Register with qubits arranged in a circle.

Parameters:

  • n (int) –

    number of qubits to place in the circle.

  • spacing (float, default: 1.0 ) –

    distance between adjacent qubits. Defaults to 1.0.

Source code in qoolqit/register.py
@classmethod
def circle(cls, n: int, spacing: float = 1.0) -> Register:
"""Initializes a Register with qubits arranged in a circle.
Args:
n: number of qubits to place in the circle.
spacing: distance between adjacent qubits. Defaults to 1.0.
"""
if n < 1:
raise ValueError("Number of qubits must be at least 1.")
if spacing <= 0:
raise ValueError("Spacing must be positive.")
if n == 1:
return cls.from_coordinates([(0.0, 0.0)])
step = 2.0 * math.pi / n
r = spacing / (2.0 * math.sin(math.pi / n))
coords = [(math.cos(step * i) * r, math.sin(step * i) * r) for i in range(n)]
return cls.from_coordinates(coords)
distances() -> dict

Distance between each qubit pair.

Source code in qoolqit/register.py
def distances(self) -> dict:
"""Distance between each qubit pair."""
pairs = all_node_pairs(self.qubits_ids)
return distances(self.qubits, pairs)
draw(
ax: Axes | None = None,
marker_size: int = 100,
node_color: str = "tab:green",
) -> None

Draw the register.

Parameters:

  • ax (Axes | None, default: None ) –

    an optional matplotlib Axes instance to draw on. If None, a new Axes will be created.

  • marker_size (int, default: 100 ) –

    size of the qubit markers in points squared. Defaults to 100.

  • node_color (str, default: 'tab:green' ) –

    color of the qubit markers. Defaults to "tab:green".

Source code in qoolqit/register.py
def draw(
self, ax: Axes | None = None, marker_size: int = 100, node_color: str = "tab:green"
) -> None:
"""Draw the register.
Args:
ax: an optional matplotlib Axes instance to draw on.
If None, a new Axes will be created.
marker_size: size of the qubit markers in points squared. Defaults to 100.
node_color: color of the qubit markers. Defaults to "tab:green".
"""
if ax is None:
_, ax = plt.subplots()
marker_radius = marker_size**0.5 / 2 # in points
annotation_offset = 1.5 * marker_radius # place label just outside the marker
coords = self._coords.detach().cpu().numpy() if _is_torch(self._coords) else self._coords
for xi, yi, qid in zip(coords[:, 0], coords[:, 1], self.qubits_ids):
ax.scatter(xi, yi, s=marker_size, color=node_color)
ax.annotate(
str(qid),
xy=(xi, yi),
xytext=(annotation_offset, annotation_offset),
textcoords="offset points",
ha="center",
va="center",
)
ax.grid(True, color="lightgray", linestyle="--", linewidth=0.7)
ax.set_axisbelow(True)
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.margins(0.1)
from_coordinates(
coords: Sequence[
Sequence[float] | NDArray[float64] | Tensor
]
| NDArray[float64]
| Tensor,
) -> Register (qoolqit.register.Register)" href="../register/#qoolqit.register.Register">Register

Initializes a Register from a sequence or array of coordinates.

Qubit IDs are assigned as integers 0,1,...,N-1, where N is the number of coordinates.

Parameters:

  • coords (Sequence[Sequence[float] | NDArray[float64] | Tensor] | NDArray[float64] | Tensor) –

    a sequence of 2D coordinates, i.e. [(x, y), ...]. Each coordinate must be castable to a numpy or torch array of shape (2,). If coords is a numpy array or a torch tensor, it must be 2D and of shape (N, 2).

Raises:

  • TypeError –

    If coords is a Mapping.

Source code in qoolqit/register.py
@classmethod
def from_coordinates(
cls,
coords: (
Sequence[Sequence[float] | npt.NDArray[np.float64] | torch.Tensor]
| npt.NDArray[np.float64]
| torch.Tensor
),
) -> Register:
"""Initializes a Register from a sequence or array of coordinates.
Qubit IDs are assigned as integers 0,1,...,N-1, where N is the number of coordinates.
Args:
coords: a sequence of 2D coordinates, i.e. [(x, y), ...].
Each coordinate must be castable to a numpy or torch array of shape (2,).
If `coords` is a numpy array or a torch tensor, it must be 2D and of shape (N, 2).
Raises:
TypeError: If `coords` is a Mapping.
"""
if isinstance(coords, Mapping):
raise TypeError(
"Register.from_coordinates expects a sequence of coordinates [(x, y), ...]; "
"pass an id-to-coordinate mapping to Register(...) directly."
)
coords_dict = {i: pos for i, pos in enumerate(coords)}
return cls(coords_dict)
from_graph(graph: DataGraph (qoolqit.graphs.DataGraph)" href="../graphs/#qoolqit.graphs.DataGraph">DataGraph) -> Register (qoolqit.register.Register)" href="../register/#qoolqit.register.Register">Register

Initializes a Register from a graph that has coordinates.

Parameters:

  • graph (DataGraph) –

    a DataGraph instance.

Source code in qoolqit/register.py
@classmethod
def from_graph(cls, graph: DataGraph) -> Register:
"""Initializes a Register from a graph that has coordinates.
Args:
graph: a DataGraph instance.
"""
if not graph.has_coords:
raise ValueError("Initializing a register from a graph requires node coordinates.")
if len(graph.nodes) == 0:
raise ValueError("Trying to initialize a register from an empty graph.")
return cls(graph.coords)
interaction_matrix() -> NDArray[float64] | Tensor

Interaction 1/r^6 between each qubit pair, as a matrix (0 on the diagonal).

Source code in qoolqit/register.py
def interaction_matrix(self) -> npt.NDArray[np.float64] | torch.Tensor:
"""Interaction 1/r^6 between each qubit pair, as a matrix (0 on the diagonal)."""
dist_matrix = _pdist(self._coords)
interactions = _fill_diagonal(dist_matrix, 1.0)
interactions **= -6
return _fill_diagonal(interactions, 0.0)
interactions() -> dict

Interaction 1/r^6 between each qubit pair.

Source code in qoolqit/register.py
def interactions(self) -> dict:
"""Interaction 1/r^6 between each qubit pair."""
return {p: 1.0 / (r**6) for p, r in self.distances().items()}
line(n: int, spacing: float = 1.0) -> Register (qoolqit.register.Register)" href="../register/#qoolqit.register.Register">Register

Initializes a Register with qubits arranged in a line.

Parameters:

  • n (int) –

    number of qubits to place in the line.

  • spacing (float, default: 1.0 ) –

    distance between adjacent qubits. Defaults to 1.0.

Source code in qoolqit/register.py
@classmethod
def line(cls, n: int, spacing: float = 1.0) -> Register:
"""Initializes a Register with qubits arranged in a line.
Args:
n: number of qubits to place in the line.
spacing: distance between adjacent qubits. Defaults to 1.0.
"""
return cls.rectangular(n, 1, row_spacing=spacing)
max_radial_distance() -> float

Maximum radial distance between all qubits.

Source code in qoolqit/register.py
def max_radial_distance(self) -> float:
"""Maximum radial distance between all qubits."""
max_radial_distance: float = max(self.radial_distances().values())
return max_radial_distance
min_distance() -> float

Minimum distance between all qubit pairs.

Source code in qoolqit/register.py
def min_distance(self) -> float:
"""Minimum distance between all qubit pairs."""
distance: float = min(self.distances().values())
return distance
radial_distances() -> dict

Radial distance of each qubit from the origin.

Source code in qoolqit/register.py
def radial_distances(self) -> dict:
"""Radial distance of each qubit from the origin."""
return {qid: _norm(coord) for qid, coord in zip(self.qubits_ids, self._coords)}
rectangular(
rows: int,
cols: int,
row_spacing: float = 1.0,
col_spacing: float = 1.0,
) -> Register (qoolqit.register.Register)" href="../register/#qoolqit.register.Register">Register

Initializes a rectangular Register of qubits.

Parameters:

  • rows (int) –

    number of rows in the rectangle.

  • cols (int) –

    number of columns in the rectangle.

  • row_spacing (float, default: 1.0 ) –

    distance between adjacent qubits in the row direction. Defaults to 1.0.

  • col_spacing (float, default: 1.0 ) –

    distance between adjacent qubits in the column direction. Defaults to 1.0.

Source code in qoolqit/register.py
@classmethod
def rectangular(
cls, rows: int, cols: int, row_spacing: float = 1.0, col_spacing: float = 1.0
) -> Register:
"""Initializes a rectangular Register of qubits.
Args:
rows: number of rows in the rectangle.
cols: number of columns in the rectangle.
row_spacing: distance between adjacent qubits in the row direction. Defaults to 1.0.
col_spacing: distance between adjacent qubits in the column direction. Defaults to 1.0.
"""
if rows < 1 or cols < 1:
raise ValueError("Number of rows and columns must be at least 1.")
if row_spacing <= 0 or col_spacing <= 0:
raise ValueError("Spacing must be positive.")
x_offset = (rows - 1) * row_spacing / 2.0
y_offset = (cols - 1) * col_spacing / 2.0
coords = [
(i * row_spacing - x_offset, j * col_spacing - y_offset)
for i in range(rows)
for j in range(cols)
]
return cls.from_coordinates(coords)
square(n: int, spacing: float = 1.0) -> Register (qoolqit.register.Register)" href="../register/#qoolqit.register.Register">Register

Initializes a square Register of qubits.

Parameters:

  • n (int) –

    number of qubits along each side of the square.

  • spacing (float, default: 1.0 ) –

    distance between adjacent qubits. Defaults to 1.0.

Source code in qoolqit/register.py
@classmethod
def square(cls, n: int, spacing: float = 1.0) -> Register:
"""Initializes a square Register of qubits.
Args:
n: number of qubits along each side of the square.
spacing: distance between adjacent qubits. Defaults to 1.0.
"""
return cls.rectangular(n, n, row_spacing=spacing, col_spacing=spacing)
triangular(
rows: int, atoms_per_row: int, spacing: float = 1.0
) -> Register (qoolqit.register.Register)" href="../register/#qoolqit.register.Register">Register

Initializes a triangular lattice Register of qubits.

Parameters:

  • rows (int) –

    number of rows in the lattice.

  • atoms_per_row (int) –

    number of qubits per row.

  • spacing (float, default: 1.0 ) –

    distance between adjacent qubits. Defaults to 1.0.

Source code in qoolqit/register.py
@classmethod
def triangular(cls, rows: int, atoms_per_row: int, spacing: float = 1.0) -> Register:
"""Initializes a triangular lattice Register of qubits.
Args:
rows: number of rows in the lattice.
atoms_per_row: number of qubits per row.
spacing: distance between adjacent qubits. Defaults to 1.0.
"""
if rows < 1 or atoms_per_row < 1:
raise ValueError("Number of rows and atoms per row must be at least 1.")
if spacing <= 0:
raise ValueError("Spacing must be positive.")
height = math.sqrt(3.0) / 2.0
x_offset = ((atoms_per_row - 1) / 2.0 + 0.5 * (rows // 2) / rows) * spacing
y_offset = (rows - 1) * height * spacing / 2.0
coords = [
((i + 0.5 * (j % 2)) * spacing - x_offset, j * height * spacing - y_offset)
for j in range(rows)
for i in range(atoms_per_row)
]
return cls.from_coordinates(coords)
SequenceCompiler(
register: Register (qoolqit.register.Register)" href="../register/#qoolqit.register.Register">Register,
drive: Drive (qoolqit.drive.Drive)" href="../drive/#qoolqit.drive.Drive">Drive,
device: Device (qoolqit.devices.Device)" href="../devices/#qoolqit.devices.Device">Device,
profile: CompilerProfile,
device_max_duration_ratio: float | None = None,
)

Compiles a QoolQit Register and Drive to a Device.

Parameters:

  • register (Register) –

    the QoolQit Register.

  • drive (Drive) –

    the QoolQit Drive.

  • device (Device) –

    the QoolQit Device.

  • profile (CompilerProfile) –

    the CompilerProfile to use.

  • device_max_duration_ratio (float | None, default: None ) –

    optionally set the program duration to a fraction of the device's maximum allowed duration.

Source code in qoolqit/execution/sequence_compiler.py
def __init__(
self,
register: Register,
drive: Drive,
device: Device,
profile: CompilerProfile,
device_max_duration_ratio: float | None = None,
) -> None:
"""Initializes the compiler.
Args:
register: the QoolQit Register.
drive: the QoolQit Drive.
device: the QoolQit Device.
profile: the CompilerProfile to use.
device_max_duration_ratio: optionally set the program duration to a fraction
of the device's maximum allowed duration.
"""
self._register = register
self._drive = drive
self._device = device
self._target_device = device._device
self._profile = profile
self._device_max_duration_ratio = device_max_duration_ratio
self._compilation_function: Callable = basic_compilation
available_default_devices() -> None

Show the default available devices in QooQit.

Source code in qoolqit/devices/device.py
def available_default_devices() -> None:
"""Show the default available devices in QooQit."""
for dev in (AnalogDevice(), AnalogDeviceWithDMM(), MockDevice()):
dev.info()