# Transition model
Multinomial logit per origin state $k$. Self-loops have logit 0 by
construction; allowed destinations $j \ne k$ contribute the linear logit
$\eta_{kj}(i,t)$:
$$
P(S_{i,t}=j \mid S_{i,t-1}=k, u_{i,t}) =
\frac{\exp(\eta_{kj}(i,t))}{\sum_{l \in \mathcal{D}(k)} \exp(\eta_{kl}(i,t))}
$$
where $\mathcal{D}(k)$ is the allowed-destination set for origin $k$ (see the
[state-space note](03-state-space.md)).
## Logit equations
Coefficients live on `TransitionRow` instances inside `TransitionParams`.
Greek-letter names match the spec; the dataclass spells them out (for
example `α[UA→AW]` is `params.ua_to_aw.alpha`).
```
η[UA→AW] = α[UA→AW]
+ β_vol · vol_t
+ β_mand · mand_t
+ β_rho · ρ_{i,t}
+ β_r · r_i
+ β_tau · (1 - τ_t / T)
η[AW→UA] = α[AW→UA] # constant ≈ -3
η[AW→PR] = α[AW→PR]
+ β_mand · mand_t
+ β_rho · ρ_{i,t}
+ β_pi · π_t
+ β_r · r_i
+ β_v · v_i
+ β_tau · (1 - τ_t / T)
η[PR→ER] = α[PR→ER]
+ β_mand · mand_t
+ β_tau · (1 - τ_t / T)
+ β_negc · (-c_t)
+ β_r · r_i
+ β_v · v_i
η[PR→SH] = α[PR→SH]
+ β_negr · (-r_i)
+ β_negv · (-v_i)
η[ER→SH] = α[ER→SH]
+ β_tir · tir_{i,t}
+ β_negc · (-c_t)
```
with $\tau_t = T - t$ so that $1 - \tau_t/T = t/T$ — closer to landfall ⇒
closer to 1.
## Bookkeeping side effects
Two transitions update the auxiliary attributes:
* `PR → ER` ⇒ `evac_path[i] = AWAY`.
* `PR → SH` ⇒ `evac_path[i] = HOME`.
(`ER → SH` does not need an update — `evac_path[i]` is already `AWAY`.)
## Vectorization
`sample_transitions` walks the four non-absorbing origin states in a fixed
order, gathers the indices of households currently in that origin, and runs
one batched softmax + categorical sample per origin. SH households are
untouched because `prev_state == State.SH` masks them out.
The inner per-state batch is the hot path. With the default parameters and
`N=10_000, T=120` the full simulation runs in about 0.3s on a contemporary
laptop — well under the 5-second target — because every household-level
operation is a NumPy reduction or column-stack.