Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/problems/abstract.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,32 @@
"""Supertype for closed-loop pulse-tuning problems (chassis types)."""
abstract type AbstractPulseTuningProblem end

"""
TunableProblem

The Piccolo problem types a [`PulseTuningProblem`](@ref) chassis can wrap, as a
single alias so the bound tracks Piccolo across versions.

Piccolo's typed-templates work introduces `AbstractQuantumControlProblem` as the
supertype of both `QuantumControlProblem` and the problem *wrappers*
(`AbstractProblemWrapper <: AbstractQuantumControlProblem`, which is what
`SamplingProblem` becomes). Before that exists, `QuantumControlProblem` is the
only problem type — `SamplingProblem` is a function returning one — so it is the
correct bound on older Piccolo.

Resolved once at load. A Piccolo upgrade invalidates Intonato's precompiled
image, so the branch is re-evaluated rather than baked in permanently.

Hardcoding either arm breaks one side: the concrete `QuantumControlProblem`
rejects the wrapper once it lands, and `AbstractQuantumControlProblem` is not a
name that can be written at all until then.
"""
const TunableProblem = if isdefined(Piccolo, :AbstractQuantumControlProblem)
Piccolo.AbstractQuantumControlProblem
else
Piccolo.QuantumControlProblem
end

"""
AbstractTuningStrategy

Expand Down
27 changes: 17 additions & 10 deletions src/problems/pulse_tuning_problem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,10 @@ After `solve!`, the QCP's trajectory and qtraj are updated in-place with the
tuned result.

# Fields
- `qcp::QuantumControlProblem`: the original (solved) optimization problem
- `qcp::P` where `P<:`[`TunableProblem`](@ref): the original (solved) optimization
problem. Parametrized rather than annotated with the alias directly so the field
stays concrete; the alias tracks Piccolo's problem hierarchy across versions and
admits the `SamplingProblem` wrapper once it exists.
- `experiment::AbstractExperiment`: hardware or simulated experiment
- `measurement_model::MeasurementModel`: measurement functions and knot indices
- `R_tr::NamedTuple`: **DEPRECATED (removed in v0.4.0)** — stored but never
Expand All @@ -163,9 +166,12 @@ tuned result.
makes the loop chase its own tail (the chained-loop-drift invariant).
- `result::Union{Nothing, TuningResult}`: populated by `solve!`
"""
mutable struct PulseTuningProblem{S<:AbstractTuningStrategy,M<:AbstractDeviceModel} <:
AbstractPulseTuningProblem
qcp::QuantumControlProblem
mutable struct PulseTuningProblem{
S<:AbstractTuningStrategy,
M<:AbstractDeviceModel,
P<:TunableProblem,
} <: AbstractPulseTuningProblem
qcp::P
experiment::AbstractExperiment
measurement_model::MeasurementModel
R_tr::NamedTuple
Expand Down Expand Up @@ -194,11 +200,12 @@ end
Construct a strategy-generic pulse tuning problem from a `QuantumControlProblem`.

**Strategy + device model (chassis/strategy split).** The problem is
parametrized as `PulseTuningProblem{S,M}` on its tuning `strategy` and
`device_model`. The chassis is strategy-agnostic — it owns the experiment /
convergence / line-search / trust-region-scalar / record loop and delegates the
inner step (and everything inner-specific, including any parameter calibration)
to the strategy via the generic strategy interface. The `strategy` field defaults
parametrized as `PulseTuningProblem{S,M,P}` on its tuning `strategy`,
`device_model`, and the wrapped problem `P` (see [`TunableProblem`](@ref)). The
chassis is strategy-agnostic — it owns the experiment / convergence /
line-search / trust-region-scalar / record loop and delegates the inner step
(and everything inner-specific, including any parameter calibration) to the
strategy via the generic strategy interface. The `strategy` field defaults
to the lightweight `IdentityStrategy` (no tuning). `device_model` defaults to a
`NominalModel` wrapping the QCP's nominal system. Pass `strategy=`/`device_model=`
to override.
Expand All @@ -213,7 +220,7 @@ error, before any device time is spent. Pass `verbose=false` to silence the
bounds-consistency warnings.
"""
function PulseTuningProblem(
qcp::QuantumControlProblem,
qcp::TunableProblem,
experiment::AbstractExperiment,
measurement_model::MeasurementModel;
R_tr::NamedTuple = (;),
Expand Down
Loading