# Analysis Support Classes

`ansupport.h` collects small generic containers analyses and analysis cores build on top of to keep per-unknown history data (past/current/future values across nonlinear iterations, time steps, or shooting periods). It has no corresponding logic in `ansupport.cpp` beyond the include - everything here is header-only template code.

## `Vector<T>`

`Vector<T>` is just `std::vector<T>` under a project-local name (the codebase avoids deriving from STL containers, so a using-alias stands in where a distinct name is wanted). `zero(vec)` assigns `0` to every element. `dataWithoutBucket(vec, bucketSize)` returns `vec.data()+bucketSize` - a pointer past the leading "bucket" slot(s) some solution/state vectors reserve (see [Namespaces and Types](common.md) and the per-unknown indexing convention where index 0 is the ground/reference unknown), for handing a raw pointer to code (e.g. a linear solver) that must not see that slot.

## `CircularBuffer<T>`

A fixed-capacity ring buffer indexed relative to a moving "current" position (`at_`), used to keep a short window of past and, in some solvers, look-ahead future values without shifting elements on every step.

- **`DepthIndex`/`DepthIndexDelta`** are `HistoryDepthIndex`/`HistoryDepthIndexDelta` (see [Namespaces and Types](common.md)) - an unsigned capacity/position type and its signed delta counterpart.
- **`add(value)`** advances the current position by one slot (wrapping at `size_`) and writes `value` there; **`remove()`** retreats the position by one slot, undoing the last `add()`. `valueCount()` tracks how many slots hold real data (caps at `size()` once the buffer has wrapped once).
- **`at(which)`** addresses a slot relative to the current position: `which=0` is the current value, `which>0` reaches `which` steps into the past, `which<0` reaches `-which` steps into the future. Both directions wrap around the buffer; `which` (or `-which`) `>= size_` throws `std::length_error`, since that would reach outside the buffer's capacity.
- **`advance(which)`** moves the current position itself by `which` slots (default 1, toward the future) without touching buffer contents - used to roll the window forward once a step is accepted.
- **`rotate(which)`** swaps the current slot's contents with the slot at `which` (default `-1`, i.e. swap current and next-future) - a move-based way to promote a tentatively computed future value into the current slot without copying.
- **`upsize(newSize)`** grows the buffer's capacity (a no-op if `newSize<=size_`), preserving the existing values' relative order by moving the tail of the old storage to the end of the new, larger storage.
- **`position()`** exposes the raw index `at_`, e.g. for a caller that needs to save/restore the buffer's rotation state.

The class is non-copyable and non-movable; it is meant to be a long-lived member of an analysis core, not a value passed around.

## `VectorRepository<T>`

`VectorRepository<T>` is `CircularBuffer<Vector<T>>` plus a shared, fixed vector `length()` applied to every slot - a history of whole solution/state vectors rather than of scalars. It is the type behind, e.g., a transient or shooting-Newton core's rolling window of past solution vectors.

- **`vector(which)`/`data(which)`** are `at(which)`/`at(which).data()` under names that read naturally for "the whole vector at this history depth"; `pastVector()`/`futureVector()` and `pastData()`/`futureData()` are shorthands for `which=1`/`which=-1`.
- **`dataWithoutBucket(which, bucketSize)`** combines `data(which)` with the free `dataWithoutBucket()` helper above, for handing a solver a pointer that skips the leading bucket slot(s).
- **`zero(which)`/`zeroPast()`/`zeroFuture()`** clear one slot's vector to `0.0` in place (a no-op if `length()==0`).
- **`upsize(newSize)`** grows capacity like `CircularBuffer::upsize()`, additionally resizing any newly appended slots to `length()`. The overload `upsize(newSize, newLength)` first resizes every existing slot's vector to `newLength` (mutating `length()` itself) and then grows capacity.

## Where this is used

Output extraction reads directly from a `VectorRepository`'s current slot: [Abstract Output Support](output.md)'s `OutputSource` has `RealVecRepo`/`ComplexVecRepo` variants that store a `const VectorRepository<T>*` and an index, and always read `data()` of the *current* slot, since a converged Newton-Raphson solution is always installed there before output variables are computed.
