Skip to content

Optimized Drive

Optimized Drive Shaper

OptimizedDriveShaper uses bayesian optimization to find drive parameters (amplitude and detuning) in order to solve a QUBO problem using quantum simulation.

It outputs both the optimized drive and a solution object containing bitstrings, counts, probabilities, and associated costs.

Features:

  • Computes normalized weights from the QUBO diagonal to support later application of the Detuning Map Modulator (DMM).
  • Uses Bayesian optimization to tune six parameters: three for the Rabi amplitude (\(\Omega\)), and three for the global detuning (\(\delta\)).
  • Executes quantum simulations at each iteration to evaluate candidate drive parameters and their performance on the QUBO.
  • Returns the final optimized drive and best QUBO solution, with full metadata (counts, probabilities, and costs).

Initialization Parameters:

Field Type Description
instance QUBOInstance Qubo instance.
config SolverConfig Configuration for solving.

Drive Parameterization

The optimized drive is built from an InterpolatedWaveform with:

Amplitude: \(\Omega = [0, \Omega_1, \Omega_2, \Omega_3, 0]\)

Detuning: \(\delta = [\delta_1, \delta_2, \delta_3]\)

These waveforms:

Always start and end in zero amplitude; Use 3 intermediate amplitude values (\(\Omega_1\) to \(\Omega_3\)) and 3 detuning values (\(\delta_1\) to \(\delta_3\)), which are the parameters optimized.

The drive starts with an InterpolatedWaveform with the points (later they are normalized to fit device constraints):

  • \(\Omega = [0, 5, 10, 5, 0]\)
  • \(\delta = [-10, 0, 10]\)

Methods Overview

  • generate(self, register: Register, instance: QUBOInstance) -> tuple[Drive, QUBOSolution]: Runs the Bayesian optimization loop and returns the optimized drive and corresponding solution. Handles fallback cases if simulation fails.

  • build_drive(self, params: list) -> Drive: Creates a Drive from a 6-element parameter list: the first 3 for amplitude, the last 3 for detuning.

  • _compute_norm_weights(self, QUBO: torch.Tensor) -> list[float]: Normalizes the QUBO diagonal weights (used in DMM shaping).

  • run_simulation(...) -> tuple[...]: Runs a simulation of the current drive on a quantum backend and returns bitstring results, probabilities, and QUBO costs.

  • compute_qubo_cost(self, bitstring: str, QUBO: torch.Tensor) -> float: Computes the QUBO cost of a specific bitstring.

Output Structure

After the final round of optimization, the following attributes are populated:

  • drive: Final Drive object with optimized waveform parameters.
  • best_cost: Minimum cost found during optimization.
  • best_bitstring: Corresponding bitstring with the lowest cost.
  • bitstrings, counts, probabilities, costs: Full result distributions as PyTorch tensors.

Example

import torch

from qubosolver import QUBOInstance
from qubosolver.config import SolverConfig, DriveShapingConfig
from qubosolver.solver import QuboSolver
from qubosolver.qubo_types import DriveType


Q = torch.tensor([[-1.0, 0.5, 0.2], [0.5, -2.0, 0.3], [0.2, 0.3, -3.0]])

instance = QUBOInstance(Q)

default_config = SolverConfig(
    use_quantum = True, drive_shaping=DriveShapingConfig(drive_shaping_method=DriveType.OPTIMIZED, optimized_n_calls = 25),
)
solver = QuboSolver(instance, default_config)

solution = solver.solve()
print(solution)
QUBOSolution(bitstrings=tensor([[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 0, 0]], dtype=torch.int32), costs=tensor([-3., -2., -1., 0.]), counts=tensor([28, 33, 29, 10], dtype=torch.int32), probabilities=tensor([0.2800, 0.3300, 0.2900, 0.1000]), solution_status=)
This will return a QUBOSolution instance, which comprehends the solution bitstrings, the counts of each bitstring, their probabilities and costs.