Skip to content

feat(trajectories): rename state_name → isomorphism_state_name and add lifted accessors - #156

Open
jack-champagne wants to merge 8 commits into
v2.0.0from
feat/lifted-solution-accessors
Open

feat(trajectories): rename state_name → isomorphism_state_name and add lifted accessors#156
jack-champagne wants to merge 8 commits into
v2.0.0from
feat/lifted-solution-accessors

Conversation

@jack-champagne

Copy link
Copy Markdown
Member

Summary

Stacked on #155. Do not merge until #155 lands.

Andy's Slack post asked for two things this PR addresses together:

  1. Rename the fixed-name accessors: state_name(qtraj) should return the user-facing symbol so that qtraj[state_name(qtraj)] returns the states the user cares about (:U, , ), and the current internal iso-form names (:Ũ⃗, :ψ̃, :ρ⃗̃) should move to isomorphism_state_name(qtraj).
  2. Lift accessors from the underlying ODESolution up to the quantum trajectory, so qtraj.t, qtraj.ψ, qtraj[:ψ] work — treat the trajectory as if it were a NamedTrajectory from the user's perspective.

Before

state_name(qtraj)      # :Ũ⃗    (intuitive?)
qtraj.solution.t       # time axis
qtraj.solution.u[end]  # final unitary

After

state_name(qtraj)              # :U             (intuitive)
isomorphism_state_name(qtraj)  # :Ũ⃗             (internal)
qtraj.t                         # time axis
qtraj.U                         # vector of unitaries
qtraj[:U]                       # same, via Symbol indexing
qtraj[state_name(qtraj)]        # same, Andy's canonical form
qtraj[isomorphism_state_name(qtraj)]  # iso form materialized at save times
qtraj.sol                       # alias for qtraj.solution (ODESolution)

Changes

state_name / isomorphism_state_name split

Trajectory state_name isomorphism_state_name
UnitaryTrajectory :U :Ũ⃗
KetTrajectory :ψ̃
MultiKetTrajectory (prefix) :ψ̃ (prefix)
DensityTrajectory :ρ⃗̃
MultiDensityTrajectory (prefix) :ρ⃗̃ (prefix)
SamplingTrajectory delegates delegates

Same split for multi-state state_names / isomorphism_state_names.

Lifted accessors via Base.getproperty / Base.getindex:

  • qtraj.t, qtraj[:t]qtraj.solution.t
  • qtraj.sol, qtraj[:sol]qtraj.solution (alias; struct field preserved for back-compat)
  • qtraj.U / qtraj.ψ / qtraj.ρqtraj.solution.u
  • qtraj[isomorphism_state_name(qtraj)] → iso form materialized at save times

propertynames(qtraj) extended so tab-completion surfaces the lifted names.

Call-site migration inside Piccolo:

  • named_trajectory_conversion.jl — all state_name(qtraj)isomorphism_state_name(qtraj) where the value is used as a NamedTrajectory component key.
  • integrators.jlstate_name / state_namesisomorphism_state_name / isomorphism_state_names for BilinearIntegrator / TimeDependentBilinearIntegrator construction.
  • control/templates/{smooth,spline,bang_bang,minimum_time,sampling}_pulse_problem.jl — likewise for iso-form indexing and constraint names.
  • control/problems.jlQuantumControlProblem delegates both state_name and new isomorphism_state_name; plain-text show prints both.

Breaking change

This is the migration surface for anyone indexing a NamedTrajectory with state_name(qtraj). They must switch to isomorphism_state_name(qtraj):

# before
U_final = traj[end][state_name(qtraj)]

# after
U_final = traj[end][isomorphism_state_name(qtraj)]

Companion PR opens in Piccolissimo.jl to migrate downstream usage there.

Test plan

  • Scoped test run (lifted accessors, common interface, display, multi/density, named traj) — all pass locally
  • Full-package CI
  • Companion Piccolissimo PR + CI

Notes

  • Kept qtraj.solution as the struct field for back-compat — .sol is an alias via getproperty. Andy floated renaming the field; deferred as a follow-up once callers have migrated to .sol.
  • Base.getproperty is defined per-concrete-type for clarity; a generic AbstractQuantumTrajectory dispatch would collide with struct field lookups.
  • propertynames is not defined for SamplingTrajectory (minor — tab-completion in the REPL still works for its real fields).

@jack-champagne
jack-champagne force-pushed the feat/lifted-solution-accessors branch 2 times, most recently from 676e20e to ac4c819 Compare April 24, 2026 07:05
jack-champagne and others added 3 commits May 3, 2026 06:09
Split src/quantum/trajectories/interface.jl into two files so rollout
entry points are easy to locate:

- trajectory_interface.jl: getters, name accessors, display
- rollouts_extensions.jl: rollout!, rollout, fidelity, _update_system!

Add Base.summary and Base.show for AbstractQuantumTrajectory producing
clean output that uses nameof(typeof(...)) instead of module-qualified
types. Update QuantumControlProblem and the verbose template banners
(SmoothPulseProblem, SplinePulseProblem, BangBangPulseProblem,
MinimumTimeProblem) to use nameof(typeof(qtraj)) / nameof(QT).
…lifted accessors

Andy requested:

  "state_name points to the actual trajectory variable that rollout will
   use and that a user will extract from solution via solution[state_name(solution)].
   Replace existing accessors with something referencing their 'internal-ness',
   naively isomorphism_state_name"

and

  "Lift up the accessors from the DifferentialEquations.jl internal solution
   to our quantum trajectory, allowing a user to access like we would a named
   trajectory (e.g., solution.t and solution.ψ or solution[:ψ])."

Changes:

  state_name(::UnitaryTrajectory)            :Ũ⃗  →  :U
  state_name(::KetTrajectory)                :ψ̃  →  :ψ
  state_name(::MultiKetTrajectory)           :ψ̃  →  :ψ   (prefix)
  state_name(::DensityTrajectory)            :ρ⃗̃  →  :ρ
  state_name(::MultiDensityTrajectory)       :ρ⃗̃  →  :ρ   (prefix)

  Add isomorphism_state_name / isomorphism_state_names returning the old
  symbols (:Ũ⃗, :ψ̃, :ρ⃗̃) for use with NamedTrajectory.

  Add lifted accessors via Base.getproperty / Base.getindex:
    qtraj.t                       → qtraj.solution.t
    qtraj.sol                     → qtraj.solution (alias)
    qtraj.U | qtraj.ψ | qtraj.ρ   → qtraj.solution.u
    qtraj[:sym]                   → getproperty(qtraj, :sym)
    qtraj[isomorphism_state_name] → materializes iso form at save times

  Keep qtraj.system / .pulse / .initial / .goal / .solution struct fields
  (backward compat). propertynames() reveals the lifted names for tab
  completion.

Update NamedTrajectory conversion, integrators, and problem templates
(SmoothPulse, Spline, BangBang, MinimumTime, Sampling) to use
isomorphism_state_name when indexing into NamedTrajectory components.

BREAKING: downstream code that indexes NamedTrajectory with
state_name(qtraj) must migrate to isomorphism_state_name(qtraj). This
affects Piccolissimo.jl's integrators (see companion PR).
…ing the refactored `isomorphism_state_name` for the isomorphic representation (`:Ũ⃗`) while retaining the new `state_name` accessor for the physical representation (`:U`).
@jack-champagne
jack-champagne force-pushed the feat/lifted-solution-accessors branch from ac4c819 to c0947f9 Compare May 4, 2026 03:26
harmoniqs-rebase-bot and others added 5 commits May 3, 2026 23:41
…ation from `main` with the new module layout documentation and refactored include structure from the feature branch.
… and renamed include paths with the base branch's new tests and docstring-enriched system update methods.
…s with `main`'s refactored rich display logic and standardized template construction logging.
…phism_state_name migration

Three call sites were still pulling the user-facing :U/:ψ symbol when the
NamedTrajectory is keyed on the iso-form symbol:

- `display/inspect.jl::_fidelity_at` (Unitary + Ket branches) — the lookup
  threw and was swallowed by an outer try/catch, silently nulling the
  inspect display's F-with-stored-phases column.
- `templates/sampling_problem.jl::_final_fidelity_constraint(::SamplingTrajectory)`
  — passed [:U1, :U2, ...] into FinalUnitaryFidelityConstraint, which uses
  the symbol as a NamedTrajectory key (:Ũ⃗1, :Ũ⃗2, ...). Latent runtime
  failure for sampling minimum-time / fidelity-constrained problems.

Also revert an unintentional `==` → `===` change in a NamedTrajectory
conversion test (UnitaryTrajectory copies `goal` into Matrix{ComplexF64},
so identity does not hold for Float64 literals), refresh the State Naming
table in src/quantum/CONTEXT.md to document the new split, and drop the
stray blank lines that crept into the `_show_header` blocks during the
ai-rebase passes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented May 20, 2026

Copy link
Copy Markdown

jack-champagne added a commit that referenced this pull request May 22, 2026
PR #155 adds new Base.summary / Base.show methods on AbstractQuantumTrajectory
plus the trajectory_interface.jl / rollouts_extensions.jl split. Public API
surface is unchanged (same exports, same signatures), so this is a
non-breaking minor bump.

Breaking changes (state_name → isomorphism_state_name etc.) are staged on
PR #156 for a future 2.0 release.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jack-champagne
jack-champagne changed the base branch from main to v2.0.0 May 22, 2026 04:18
@jack-champagne
jack-champagne marked this pull request as ready for review May 22, 2026 04:18
@jack-champagne

Copy link
Copy Markdown
Member Author

what might really be missing from this breaking change is actually seperating and thinking carefully about the split between problem and solution. right now qtraj is a little abstract and that might be able to be fixed with better accessors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant