Skip to content

Commit

Permalink
Add piecewise backend function (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpmoutinho authored Dec 17, 2024
1 parent 2c762ca commit 1f4f425
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 11 deletions.
10 changes: 7 additions & 3 deletions qadence2_platforms/backends/_base_analog/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@ def from_instructions(
sequence: Sequence,
inputs: dict[str, Alloc],
instructions: list[Assign | QuInstruct],
allow_time_dependent: bool = False,
) -> list[NamedPulse]:
variables = dict()
temp_vars: dict[str, Any] = dict()

for var in inputs:
# inputs[var].size holds the points to interpolate time-dependent functions
if inputs[var].size > 1:
raise TypeError("This platform cannot handle time modulated variables.")

variables[var] = sequence.declare_variable(var)
if allow_time_dependent:
variables[var] = sequence.declare_variable(var, size=inputs[var].size)
else:
raise TypeError("This platform cannot handle time modulated variables.")
else:
variables[var] = sequence.declare_variable(var)

pulses = []
for instruction in instructions:
Expand Down
56 changes: 49 additions & 7 deletions qadence2_platforms/backends/analog/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

import numpy as np
from pulser import Pulse
from pulser.parametrized.variable import VariableItem
from pulser.parametrized.variable import VariableItem, Variable
from pulser.sequence import Sequence
from pulser.waveforms import ConstantWaveform, BlackmanWaveform
from pulser.waveforms import ConstantWaveform, BlackmanWaveform, RampWaveform, CompositeWaveform

from qadence2_platforms.backends._base_analog.functions import (
Direction,
Expand Down Expand Up @@ -45,17 +45,19 @@ def dyn_pulse(
"""
Dynamic pulse to simulate a specific time-dependent hamiltonian for neutral-atom devices.
:param sequence: a `pulser.sequence.Sequence` instance
:param duration: duration of the pulse in nanoseconds
:param amplitude: amplitude of the pulse in rad/µs
:param detuning: detuning of the pulse in rad/s
:param phase: phase in rad
Args:
sequence: a `pulser.sequence.Sequence` instance
duration: duration of the pulse in dimensionless units
amplitude: amplitude of the pulse in dimensionless units
detuning: detuning of the pulse in dimensionless units
phase: phase in radians
"""
max_amp = sequence.device.channels["rydberg_global"].max_amp or DEFAULT_AMPLITUDE
max_abs_detuning = (
sequence.device.channels["rydberg_global"].max_abs_detuning or DEFAULT_DETUNING
)

# FIXME: Centralize unit converions
duration *= 1000 * 2 * np.pi / max_amp # type: ignore
amplitude *= max_amp # type: ignore
detuning *= max_abs_detuning # type: ignore
Expand All @@ -67,6 +69,46 @@ def dyn_pulse(
sequence.add(p, channel="global")


def piecewise_pulse(
sequence: Sequence,
duration: Variable | VariableItem,
amplitude: Variable,
detuning: Variable,
phase: VariableItem | float,
**_: Any,
) -> None:
"""
Dynamic pulse to simulate a specific piecewise time-dependent hamiltonian for neutral-atom devices.
Args:
sequence: a `pulser.sequence.Sequence` instance
duration: duration of the pulse in dimensionless units
amplitude: amplitude of the pulse in dimensionless units
detuning: detuning of the pulse in dimensionless units
phase: phase in radians
"""
max_amp = sequence.device.channels["rydberg_global"].max_amp or DEFAULT_AMPLITUDE
max_abs_detuning = (
sequence.device.channels["rydberg_global"].max_abs_detuning or DEFAULT_DETUNING
)

dur_factor = 1000 * 2 * np.pi / max_amp # type: ignore
amp_factor = max_amp # type: ignore
det_factor = max_abs_detuning # type: ignore

# Needed so a size = 1 variable is made iterable
duration = [duration] if isinstance(duration, VariableItem) else duration

for i, dur in enumerate(duration):
amp_wf = RampWaveform(
dur * dur_factor, amplitude[i] * amp_factor, amplitude[i + 1] * amp_factor
)
det_wf = RampWaveform(
dur * dur_factor, detuning[i] * det_factor, detuning[i + 1] * det_factor
)
sequence.add(Pulse(amp_wf, det_wf, phase), "global")


def rx(
sequence: Sequence,
angle: VariableItem | float,
Expand Down
2 changes: 1 addition & 1 deletion qadence2_platforms/backends/analog/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def from_model(model: Model, register: RegisterLayout) -> Sequence:

seq.config_detuning_map(detuning_map, "dmm_0")

pulses = from_instructions(seq, model.inputs, model.instructions)
pulses = from_instructions(seq, model.inputs, model.instructions, allow_time_dependent=True)

for pulse in pulses:
fn: Optional[Callable] = getattr(
Expand Down

0 comments on commit 1f4f425

Please sign in to comment.