Description
QoolQit should support the sequential composition of Drive objects that have different phases.
A Drive associates amplitude and detuning waveforms with a single phase. Pulser supports this use case by scheduling consecutive Pulse objects with different phases, so QoolQit should be able to express and compile the equivalent program.
Reference behavior in Pulser
The following sequence applies two consecutive pulses. The first pulse has phase $\pi$ and the second has phase $0$.
import numpy as np
from pulser import Pulse, Register, Sequence
from pulser.devices import MockDevice
from pulser.waveforms import RampWaveform
device = MockDevice
register = Register.rectangle(1, 3)
pulse_1 = Pulse(
amplitude=RampWaveform(start=0.0, stop=1.0, duration=1000),
detuning=RampWaveform(start=0.0, stop=1.0, duration=1000),
phase=np.pi,
)
pulse_2 = Pulse(
amplitude=RampWaveform(start=1.0, stop=0.0, duration=1000),
detuning=RampWaveform(start=1.0, stop=0.0, duration=1000),
phase=0.0,
)
sequence = Sequence(register, device)
sequence.declare_channel("ryd", "rydberg_global")
sequence.add(pulse_1, "ryd", protocol="no-delay")
sequence.add(pulse_2, "ryd", protocol="no-delay")
sequence.draw()
Desired QoolQit API
The equivalent QoolQit program should be expressible with the existing composition operator:
import numpy as np
from qoolqit import Drive, MockDevice, Register
from qoolqit.waveforms import RampWaveform
device = MockDevice
register = Register.rectangular(1, 3)
amp_waveform = RampWaveform(
initial_value=0.0,
final_value=1.0,
duration=1000,
)
det_waveform = RampWaveform(
initial_value=0.0,
final_value=1.0,
duration=1000,
)
drive_1 = Drive(
amplitude=amp_waveform,
detuning=det_waveform,
phase=np.pi,
)
amp_waveform = RampWaveform(
initial_value=1.0,
final_value=0.0,
duration=1000,
)
det_waveform = RampWaveform(
initial_value=1.0,
final_value=0.0,
duration=1000,
)
drive_2 = Drive(
amplitude=amp_waveform,
detuning=det_waveform,
phase=0.0,
)
composite_drive = drive_1 >> drive_2
composite_drive.draw()
When compiled through the existing QoolQit compilation path, composite_drive should produce two consecutive Pulser pulses and preserve the phase of each segment.
Proposed design
Introduce an ordered composite representation that preserves each component drive. For example:
class CompositeDrive(Drive):
drives: tuple[Drive, ...]
The exact inheritance and storage type can be adjusted to fit the current data model. The important requirement is that the phase remains attached to each individual drive segment.
Suggested behavior:
drive_1 >> drive_2 returns a composite representation when the phases differ.
- Chained composition is supported, for example
drive_1 >> drive_2 >> drive_3.
- The total duration is the sum of the component durations.
draw() displays the full composed drive and makes phase changes or segment boundaries visible.
- Existing behavior for drives with the same phase remains backward-compatible; such drives may continue to use the current optimized representation.
Acceptance criteria
Expected outcome
QoolQit can represent and compile piecewise drives whose phase changes between segments, with behavior equivalent to scheduling consecutive Pulser pulses with different phases.
Issue Breakdown
Break it down into 2/3 separate PRs
To allow compilation to multiple phased pulses:
Finally support Drive composition w/ different phases:
Description
QoolQit should support the sequential composition of
Driveobjects that have different phases.A
Driveassociates amplitude and detuning waveforms with a single phase. Pulser supports this use case by scheduling consecutivePulseobjects with different phases, so QoolQit should be able to express and compile the equivalent program.Reference behavior in Pulser
The following sequence applies two consecutive pulses. The first pulse has phase$\pi$ and the second has phase $0$ .
Desired QoolQit API
The equivalent QoolQit program should be expressible with the existing composition operator:
When compiled through the existing QoolQit compilation path,
composite_driveshould produce two consecutive Pulser pulses and preserve the phase of each segment.Proposed design
Introduce an ordered composite representation that preserves each component drive. For example:
The exact inheritance and storage type can be adjusted to fit the current data model. The important requirement is that the phase remains attached to each individual drive segment.
Suggested behavior:
drive_1 >> drive_2returns a composite representation when the phases differ.drive_1 >> drive_2 >> drive_3.draw()displays the full composed drive and makes phase changes or segment boundaries visible.Acceptance criteria
Driveobjects with different phases can be composed with>>without an error or loss of information.draw()works for the composed object and clearly represents the phase transition.Expected outcome
QoolQit can represent and compile piecewise drives whose phase changes between segments, with behavior equivalent to scheduling consecutive Pulser pulses with different phases.
Issue Breakdown
Break it down into 2/3 separate PRs
To allow compilation to multiple phased pulses:
Drive._to_pulser() -> tuple[pulser.Pulse]to always return a tuple of pulses. The rationale is that when making a pulser.Sequence, pulses are appended it one-by-one. This also leaves unchanged the single pulse/drive compilation behavior.pulser.Pulses to thepulser.SequenceFinally support Drive composition w/ different phases:
CompositeDriveas a tuple of Drives. Different phases are naturally stored in each Drive