Skip to content

Results are limited to the current section: Application solving tools

Product news

qubosolver.drive_shaping

Drive shaping algorithms for generating quantum drive schedules.

Provides several algorithms for constructing amplitude and detuning waveforms used to solve QUBO problems on neutral-atom hardware.

Modules:

qubosolver.drive_shaping.local_energy_scale

Section titled “ qubosolver.drive_shaping.local_energy_scale ”

Local-energy-scale heuristic drive schedule generation for QUBO solving.

Functions:

  • build_drive –

    Generate a local-energy-scale heuristic drive for QUBO solving.

build_drive(instance: Instance (qubosolver.Instance)" href="../qubosolver/#qubosolver.Instance">Instance, register: qoolqit.Register, *, device: qoolqit.Device, dmm: bool = True, kappa: float = 0.1) -> qoolqit.Drive

Generate a local-energy-scale heuristic drive for QUBO solving.

For each qubit, the local physical energy scale is

Ei=∣δi(T)∣+∑j≠i∣Vij∣,E_i = |\delta_i(T)| + \sum_{j \neq i} |V_{ij}|,

where δi(T)\delta_i(T) is the final detuning effectively applied to qubit ii and VijV_{ij} is the physical interaction generated by the embedded register.

The peak Rabi frequency is defined as

ωmax⁡=κ⋅meani(Ei).\omega_{\max} = \kappa \cdot \text{mean}_i(E_i).

When DMM is available, the final local detunings are encoded as

δi(T)=δg(T)+δdmm(T)⋅wi,\delta_i(T) = \delta_g(T) + \delta_{\text{dmm}}(T) \cdot w_i,

with

δg(T)=dmax⁡,δdmm(T)=−(dmax⁡−dmin⁡),wi=dmax⁡−didmax⁡−dmin⁡.\delta_g(T) = d_{\max}, \quad \delta_{\text{dmm}}(T) = -(d_{\max} - d_{\min}), \quad w_i = \frac{d_{\max} - d_i}{d_{\max} - d_{\min}}.

Without DMM, all atoms receive the same final global detuning

δi(T)=δg(T)=meani(di).\delta_i(T) = \delta_g(T) = \text{mean}_i(d_i).

The resulting amplitude and detuning waveforms are clamped or rescaled when necessary so they remain compilable on the target device.

Parameters:

Returns:

Source code in qubosolver/drive_shaping/local_energy_scale.py
def build_drive(
instance: Instance,
register: qoolqit.Register,
*,
device: qoolqit.Device,
dmm: bool = True,
kappa: float = 0.1,
) -> qoolqit.Drive:
r"""Generate a local-energy-scale heuristic drive for QUBO solving.
For each qubit, the local physical energy scale is
Ei=∣δi(T)∣+∑j≠i∣Vij∣,E_i = |\delta_i(T)| + \sum_{j \neq i} |V_{ij}|,Ei​=∣δi​(T)∣+j=i∑​∣Vij​∣,
where δi(T)\delta_i(T)δi​(T) is the final detuning effectively applied to qubit
iii and VijV_{ij}Vij​ is the physical interaction generated by the embedded
register.
The peak Rabi frequency is defined as
ωmax⁡=κ⋅meani(Ei).\omega_{\max} = \kappa \cdot \text{mean}_i(E_i).ωmax​=κ⋅meani​(Ei​).
When DMM is available, the final local detunings are encoded as
δi(T)=δg(T)+δdmm(T)⋅wi,\delta_i(T) = \delta_g(T) + \delta_{\text{dmm}}(T) \cdot w_i,δi​(T)=δg​(T)+δdmm​(T)⋅wi​,
with
\delta_g(T) = d_{\max}, \quad
\delta_{\text{dmm}}(T) = -(d_{\max} - d_{\min}), \quad
w_i = \frac{d_{\max} - d_i}{d_{\max} - d_{\min}}.
Without DMM, all atoms receive the same final global detuning
δi(T)=δg(T)=meani(di).\delta_i(T) = \delta_g(T) = \text{mean}_i(d_i).δi​(T)=δg​(T)=meani​(di​).
The resulting amplitude and detuning waveforms are clamped or rescaled
when necessary so they remain compilable on the target device.
Args:
instance: The QUBO instance whose diagonal encodes target detunings.
register: The physical register the drive will run on.
device: Target quantum device providing the hardware limits.
dmm: Whether to use the Detuning Map Modulator for local control.
kappa: Ratio between the peak Rabi frequency and the average local
physical energy scale.
Returns:
A drive ready for compilation and execution.
"""
# Hardware bounds
specs = device.specs
max_seq_duration: float = specs["max_duration"] or 1000.0
use_dmm = dmm
if use_dmm and not support_dmm(device):
logging.warning(
"dmm=True was requested but device %r does not support a DMM channel; "
"falling back to a global detuning drive.",
device,
)
use_dmm = False
if specs.get("max_amplitude") is not None and specs.get("max_abs_detuning") is not None:
device_max_amplitude = specs["max_amplitude"]
device_max_abs_detuning = specs["max_abs_detuning"]
assert device_max_amplitude is not None # nosec B101
assert device_max_abs_detuning is not None # nosec B101
det_amp_ratio = device_max_amplitude / device_max_abs_detuning
if kappa < det_amp_ratio:
logger.warning(
f"local_energy_scale_kappa is too small ({kappa}), you're likely to get a "
f"qoolqit CompilationError. Set it above {det_amp_ratio}."
)
# Target local final detunings.
d = (-0.5 * torch.diag(instance.matrix)).detach().cpu()
delta_g_T, delta_dmm_T, weights, use_dmm = _detunings(d, use_dmm)
# Final detuning effectively applied to each qubit:
#
# delta_i(T) = delta_g(T) + delta_dmm(T) * w_i.
#
# with delta_dmm(T) = 0 when dmm is disabled
final_local_detunings = delta_g_T + delta_dmm_T * weights
# Physical interactions generated by the embedded register:
#
# V_ij = 1 / r_ij**6.
#
# For each qubit i, compute:
#
# sum_{j != i} |V_ij|.
interaction_scale = matrix.as_tensor(register.interaction_matrix()).abs().sum(dim=0)
# Local physical energy scale:
#
# E_i = |delta_i(T)| + sum_{j != i} |V_ij|.
local_energy_scale = final_local_detunings.abs() + interaction_scale
# Average local physical energy scale:
#
# E_mean = (1 / n) * sum_i E_i.
mean_local_energy_scale = local_energy_scale.mean().item()
# Local-energy-scale mixing rule:
#
# omega_max = kappa * E_mean.
omega_max = kappa * mean_local_energy_scale
# Clamp the amplitude to what can be compiled for this device and register.
max_amplitude = max_virtual_amplitude(device, register)
if omega_max > max_amplitude:
logger.info(
f"The local-energy-scale drive amplitude ({omega_max}) exceeds the maximum "
f"amplitude compilable on the device for this register "
f"({max_amplitude}); clamping to it."
)
omega_max = max_amplitude
# Ensure that the target detunings remain compilable for the selected amplitude.
max_detuning = detuning_amplitude_ratio(device) * omega_max * (1.0 - 1e-3)
max_abs_d = d.abs().max().item()
if max_abs_d > max_detuning:
logger.info(
f"The local-energy-scale detuning ({max_abs_d}) exceeds the maximum detuning "
f"compilable on the device for this amplitude ({max_detuning}); "
f"scaling the detuning down."
)
d = d * (max_detuning / max_abs_d)
# Recompute the DMM encoding after rescaling the target local detunings.
delta_g_T, delta_dmm_T, weights, use_dmm = _detunings(d, use_dmm)
# Keep the initial detuning rule identical to the standard heuristic drive.
delta_0 = -d.abs().max().item()
# Amplitude waveform: 0 -> omega_max -> omega_max -> 0.
eps = 1e-9
amp_wave = qoolqit.InterpolatedWaveform(
max_seq_duration,
[eps, omega_max, omega_max, eps],
)
# Global detuning waveform: initial negative value -> final target.
det_wave = qoolqit.InterpolatedWaveform(
max_seq_duration,
[delta_0, delta_0, delta_g_T, delta_g_T],
)
# Optional DMM weighted detunings.
wdetunings = None
if use_dmm:
energy_scale = device._target_amp / omega_max
wdetunings = constant_weighted_dmm(
weights.tolist(),
max_seq_duration,
final_detuning=delta_dmm_T,
device=device,
energy_scale=energy_scale,
)
return qoolqit.Drive(
amplitude=amp_wave,
detuning=det_wave,
dmm=wdetunings,
)

qubosolver.drive_shaping.proportional_diagonal

Section titled “ qubosolver.drive_shaping.proportional_diagonal ”

Proportional-diagonal drive schedule generation for QUBO solving.

Functions:

  • build_drive –

    Generate a proportional-diagonal drive schedule for QUBO solving.

build_drive(instance: Instance (qubosolver.Instance)" href="../qubosolver/#qubosolver.Instance">Instance, register: qoolqit.Register, *, device: qoolqit.Device, dmm: bool = True, kappa: float = 1.0) -> qoolqit.Drive

Generate a proportional-diagonal drive schedule for QUBO solving.

Constructs amplitude and detuning waveforms from the QUBO diagonal coefficients, clamped so they stay within what the compiler can realize on device for register. When DMM is available, per-atom detuning weights are computed so that the final local detuning encodes the QUBO diagonal.

Parameters:

Returns:

Source code in qubosolver/drive_shaping/proportional_diagonal.py
def build_drive(
instance: Instance,
register: qoolqit.Register,
*,
device: qoolqit.Device,
dmm: bool = True,
kappa: float = 1.0,
) -> qoolqit.Drive:
"""Generate a proportional-diagonal drive schedule for QUBO solving.
Constructs amplitude and detuning waveforms from the QUBO diagonal
coefficients, clamped so they stay within what the compiler can realize
on `device` for `register`. When DMM is available, per-atom detuning
weights are computed so that the final local detuning encodes the QUBO
diagonal.
Args:
instance: The QUBO instance whose diagonal encodes target detunings.
register: The physical register the drive will run on.
device: Target quantum device (provides hardware limits).
dmm: Whether to use the Detuning Map Modulator for local control.
kappa: Ratio between peak Rabi frequency and peak detuning.
Returns:
A drive ready for compilation and execution.
"""
# Hardware bounds
specs = device.specs
max_seq_duration: float = specs["max_duration"] or 1000.0
use_dmm = dmm
if use_dmm and not support_dmm(device):
logging.warning(
"dmm=True was requested but device %r does not support a DMM channel; "
"falling back to a global detuning drive.",
device,
)
use_dmm = False
if specs.get("max_amplitude") is not None and specs.get("max_abs_detuning") is not None:
max_amplitude = specs["max_amplitude"]
max_abs_detuning = specs["max_abs_detuning"]
assert max_amplitude is not None and max_abs_detuning is not None # nosec B101
det_amp_ratio = max_amplitude / max_abs_detuning
if kappa < det_amp_ratio:
logger.warning(
f"proportional_diagonal_kappa is too small ({kappa}), you're likely to get a "
f"qoolqit CompilationError. Set it above {det_amp_ratio}."
)
n = instance.size
# Target local final detunings
d = (-0.5 * torch.diag(instance.matrix)).cpu().numpy()
d_min = float(np.min(d))
d_max = float(np.max(d))
omega_max = kappa * float(np.max(np.abs(d)))
max_amplitude = max_virtual_amplitude(device, register)
if omega_max > max_amplitude:
logger.info(
f"The proportional-diagonal drive amplitude ({omega_max}) exceeds the maximum "
f"amplitude compilable on the device for this register "
f"({max_amplitude}); clamping to it."
)
omega_max = max_amplitude
max_detuning = detuning_amplitude_ratio(device) * omega_max * (1.0 - 1e-3)
max_abs_d = float(np.max(np.abs(d)))
if max_abs_d > max_detuning:
logger.info(
f"The proportional-diagonal detuning ({max_abs_d}) exceeds the maximum detuning "
f"compilable on the device for this amplitude ({max_detuning}); "
f"scaling the detuning down."
)
d = d * (max_detuning / max_abs_d)
d_min = float(np.min(d))
d_max = float(np.max(d))
if use_dmm:
# Final global detuning is the top value, DMM pulls down locally
delta_g_T = d_max
# DMM convention required by WeightedDetuning:
# waveform must be <= 0
spread = max(0.0, d_max - d_min)
# if spread > 1e-15 and delta_dmm_max > 0.0:
if spread > 1e-15:
delta_dmm_T = -spread # must be <= 0
denom = d_max - d_min
weights = ((d_max - d) / denom).clip(0.0, 1.0).tolist()
else:
use_dmm = False
delta_dmm_T = 0.0
weights = [0.0] * n
else:
# No DMM: use a single global final detuning
delta_g_T = np.mean(d)
delta_dmm_T = 0.0
weights = [0.0] * n
# How to get max detuning ?
delta_0 = -np.max(np.abs(d))
# Amplitude waveform: 0 -> plateau -> 0
eps = 1e-9
amp_wave = qoolqit.InterpolatedWaveform(
max_seq_duration,
[eps, omega_max, omega_max, eps],
)
# Global detuning waveform: initial negative -> final target
det_wave = qoolqit.InterpolatedWaveform(
max_seq_duration,
[delta_0, delta_0, delta_g_T, delta_g_T],
)
# DMM weighted detunings
wdetunings = None
if use_dmm:
energy_scale = device._target_amp / omega_max
wdetunings = constant_weighted_dmm(
weights,
max_seq_duration,
final_detuning=delta_dmm_T,
device=device,
energy_scale=energy_scale,
)
return qoolqit.Drive(
amplitude=amp_wave,
detuning=det_wave,
dmm=wdetunings,
)