You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: agent-docs/01-representation.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -150,6 +150,8 @@ A few notes on the structure:
150
150
151
151
The third layer has a non-obvious consequence: **representation degeneracies in state prep** (and to a lesser extent measurement). Multiple distinct parameter-vector values can map to the same physical noisy SPAM, because what you're modeling is the *combined* prep-plus-noisy-op, and the split between "ideal prep" and "noisy op" is non-unique. This is a sort of "gauge freedom" (although not the kind relevant to gauge optimization). If you're debugging a fit and SPAM's contributions to the parameter vector look weird, this might be why.
152
152
153
+
**Instruments** extend the same pattern to mid-circuit measurements. Each member factors as a measurement effect followed by a post-measurement CPTP gate, `I_k(ρ) = G_k(E_k^½ ρ E_k^½)` with `E_k = I_k†(I)`, and is represented as a single `ComposedOp([RootConjOperator(E_k), G_k])`. The effects `{E_k}` are gathered into one shared [`ComposedPOVM`](../pygsti/modelmembers/povms/composedpovm.py) — its completeness `Σ_k E_k = I` is exactly the instrument's joint trace preservation — and each `G_k` is parameterized independently (a CP-constrained `G_k` makes *that member* CP). Build these with the classmethods `Instrument.from_effects` / `Instrument.from_cptr_superops` (logic in [`modelmembers/instruments/_construction.py`](../pygsti/modelmembers/instruments/_construction.py)), or reach them via `convert(instrument, 'CPTPLND', basis)` / `set_all_parameterizations('CPTPLND')`. An n-outcome instrument needs only **n effects and n gates**. Note the shared-POVM layout makes the *later* members' parameter indices **non-contiguous** (they share the early POVM indices but own late gate indices); this is handled, but it's why `_submember_rpindices` can be an array rather than a slice.
154
+
153
155
## Pitfalls and gotchas
154
156
155
157
-**`gpindices` is the central glue.** Every `ModelMember` has a `gpindices` slice or array that says "I own indices `[a, b)` of the parent Model's `_paramvec`." A `gpindices` of `None` means "unallocated — will be assigned on add-to-model." Copying a member from one Model to another typically requires rebinding indices; `Model._rebuild_paramvec()` is the canonical way to force a fresh allocation.
0 commit comments