# dcvar 0.9.3

## Bug fixes and maintenance

- Fit constructors now preserve Stan file and cache metadata consistently across
  constant, dynamic, HMM, covariate, multilevel, and SEM fits.
- Extractor probability arguments are validated consistently before posterior
  summaries are computed.
- Removed unused internal helpers superseded by the unified dynamic engine, the
  content-hash Stan cache, the current multilevel simulator behavior, and the
  scale-aware simulation path.

## Tests

- Retargeted regression coverage from deleted internals to the live routing,
  extractor, Stan cache, and simulation helpers.

# dcvar 0.9.2

## New features

- `applicability_check()` screens a fitted constant copula-VAR for the
  floor/ceiling pile-up pathology, combining a boundary-atom signal, a
  dynamics-collapse signal (fitted self-lags against an OLS VAR(1) anchor and an
  optional normal-margin reference fit), and slant/convergence flags into a
  `suitable`/`caution`/`unsuitable` verdict with a recommendation. Has a `print`
  method. Convergence problems (divergences, elevated split-Rhat) block a
  `suitable` verdict; the boundary atom requires a genuine tie at the bound; and
  the dynamics-collapse anchor is sign-agnostic.

# dcvar 0.9.1

## Bug fixes

- SEM and multilevel simulators now use and record the same residual scale for
  skew-normal and gamma innovations when a non-default `sigma` is supplied.
- `sigma_trajectory()` now reports skew-normal time-varying scales on the
  residual-SD scale, matching simulation truth and the gamma convention.
- Gaussian-copula exponential posterior-predictive draws now clamp inverse-CDF
  uniforms before applying `log1m()`, matching the Clayton guard.
- Missing-data diagnostics now report the number of interior missing rows,
  rather than the total number of incomplete rows.
- The README HMM switching example now uses the valid lowercase `phi` selector.

## Tests

- Strengthened multilevel TV `fitted()`/`predict()` tests so they exercise
  time-varying unit-level Phi paths and `sigma_t` intervals away from `t = 1`.
- Added regression tests for skew-normal/gamma simulator scale conventions and
  skew-normal `sigma_trajectory()` scale reporting.

# dcvar 0.9.0

## Time-varying SEM and multilevel extensions

- `dcvar_sem(method = "indicator")` gains `tv_phi` and `tv_sigma`, using a new
  `sem_tv_mixed.stan` engine with optional masked random walks for latent VAR
  coefficients, log-scale scale paths, and time-varying Gaussian-copula
  correlation. The naive score method now rejects TV SEM options explicitly.
- `dcvar_multilevel()` gains `tv_phi` and `tv_sigma`, using a new
  `multilevel_tv_mixed.stan` engine. To reduce the main identifiability risk,
  time-varying Phi is implemented as a shared population drift around
  unit-specific random baselines rather than independent per-unit random walks.
- SEM and multilevel simulators now accept time-varying Phi, scale, and
  correlation paths where supported. New `dcvar_sem_tv_fit` and
  `dcvar_multilevel_tv_fit` subclasses expose `phi_trajectory()`,
  `sigma_trajectory()`, `rho_trajectory()`, `dependence_summary()`, `coef()`,
  and `var_params()` methods; multilevel TV fits also use the per-unit-time Phi
  path in `fitted()` and `predict()`.

# dcvar 0.8.0

## Margins: full SEM and multilevel family support

- `dcvar_sem()` (indicator and naive score methods) and `dcvar_multilevel()` now
  accept homogeneous `"skew_normal"` and `"gamma"` margins in addition to
  `"normal"` and `"exponential"`. These fits route through the existing generic
  mixed-margin Stan engines (`sem_mixed.stan`, `sem_naive_mixed.stan`, and
  `multilevel_mixed.stan`) by passing the same family code for both dimensions.
- Data preparation, default initial values, `coef()`, `var_params()`,
  diagnostics, and diagnostic plots understand the mixed-engine parameter layout
  for these homogeneous fits, including per-dimension `shape_gam[d]` outputs for
  gamma margins.

# dcvar 0.7.0

## New feature: full Markov-switching HMM

- `dcvar_hmm()` gains a `switch` argument that lets the VAR(1) intercepts (`mu`),
  the VAR coefficients (`Phi`, with `"ar"`/`"cross"`/coefficient-name
  granularity), and the residual scales become state-specific, in addition to
  the always state-specific copula correlation. `switch = "rho"` (the default)
  reproduces the previous regime-switching-correlation model exactly. The copula
  correlation is the label-switching anchor (`ordered` `z_rho`), so `rho` must
  remain in `switch` whenever other components switch; states are reported in
  increasing-correlation order.
- The marginal distribution **family** can now switch by state: `margins` accepts
  a length-K list of per-state family specifications, for example
  `margins = list(c("normal", "normal"), c("exponential", "gamma"))`, with a
  matching `skew_direction` (a length-2 vector recycled across states, or a
  length-K list). The list is consumed in increasing-`rho` order, and a warning
  is emitted when families differ across states so the ordering can be verified.
- These richer configurations are served by a new internal Stan engine,
  `inst/stan/hmm_switching.stan`, selected automatically; the default
  `dcvar_hmm()` keeps routing to the specialised legacy files, so existing fits
  and posteriors are unchanged. `dcvar_stan_path("hmm")` is unchanged; pass
  `stan_file = dcvar_stan_path("hmm_switching")` to request the engine explicitly.
- New `hmm_state_params()` returns the per-state intercepts, effective VAR(1)
  coefficient matrices, margin scales, and family labels. `coef()`, `var_params()`,
  `print()`, and `summary()` report state-indexed parameters for switching fits;
  `fitted()` returns the gamma-weighted one-step prediction. Marginal prediction
  intervals, PIT, and posterior-predictive plots are not yet available for
  state-specific fits and abort with a pointer to `hmm_state_params()`.

# dcvar 0.6.0

## Internal: unified dynamic Stan engine

- The time-varying DC-VAR path (`dcvar()` with `tv_phi` / `tv_sigma`) and the
  drift covariate model (`dcvar_covariate(drift = TRUE)`) are now served by a
  single generic Stan engine, `inst/stan/dcvar_dynamic.stan`. It extends the
  time-varying mixed-margin model with a covariate predictor on the Fisher-z
  correlation and the covariate model's residual-drift convention, unifying the
  two model families behind one Fisher-z predictor
  `z_rho[t] = z_rho_init + X[t+1]' beta + drift[t]`.
- This is an internal consolidation with no change to the public interface:
  `dcvar()` and `dcvar_covariate()` keep their signatures, defaults, S3 classes,
  and model strings, and the posteriors are unchanged. The plain (non
  time-varying) `dcvar()` and the no-drift `dcvar_covariate(drift = FALSE)`
  model continue to use their specialised Stan files unchanged, so no refit is
  needed. The covariate model exposes its intercept as `beta_0` exactly as
  before (now a transformed-parameter alias of the sampled `z_rho_init`).
- `dcvar_stan_path()` continues to return the Stan file matching each exported
  `prepare_*()` data contract (e.g. `dcvar_stan_path("dcvar_covariate")` still
  returns the legacy covariate model). The unified engine is selected internally
  by the fit wrappers; pass `stan_file = dcvar_stan_path("dcvar_dynamic")` to
  request it explicitly.
- For an all-normal, constant-scale fit (the covariate model) the engine uses
  the z-score Gaussian-copula form on the standardized residuals, reproducing
  the legacy covariate likelihood term-by-term; an independent recomputation of
  the log-likelihood is checked in the test suite. The copula fast path is
  guarded so it never applies to a time-varying scale.

# dcvar 0.5.0

## New feature: fully time-varying DC-VAR

- `dcvar()` gains `tv_phi` and `tv_sigma` flags. With `tv_phi = TRUE` the
  four VAR(1) coefficients (the AR effects phi11/phi22 and the cross-lagged
  effects phi12/phi21) evolve as independent non-centered random walks around
  the constant baseline `Phi`; with `tv_sigma = TRUE` the residual scales of
  normal and skew-normal dimensions evolve as log-scale random walks around
  their baselines. Combined with the always time-varying copula correlation
  rho(t) and per-variable (mixed) margins, every model component except the
  intercepts can now vary over time. Both flags default to `FALSE`, which
  reproduces the previous behavior exactly (same Stan models, same draws).
- `tv_phi` also accepts a character selector so that only a subset of the
  VAR coefficients varies: `"ar"` (the autoregressive effects phi11, phi22 --
  e.g. for changing emotional inertia / critical slowing down), `"cross"`
  (the cross-lagged effects phi12, phi21), or specific names such as
  `c("phi11", "phi22")`. Only the selected coefficients get random-walk
  parameters (the others stay at their constant baseline), which improves
  identifiability on short series and lets you test a sharp hypothesis.
  `phi_trajectory()` still returns all four coefficients (the fixed ones as
  constant paths); `coef()`/`var_params()` label `tau_phi` by coefficient
  name.
- Flag-on fits use one generic Stan model (`dcvar_tv_mixed.stan`) for all
  margin specifications, dispatching on per-dimension family codes; with both
  flags off in that model the target density is identical term-by-term to
  `dcvar_mixed_ncp.stan`, so the TV model exactly nests the classic DC-VAR.
  New walk priors `prior_tau_phi_rate` (default 0.025) and
  `prior_tau_sigma_rate` (default 0.05) shrink toward the constant model;
  see the new "Recommended workflow" section in `?dcvar` for the model
  ladder.
- New fit subclass `dcvar_tv_fit` (inherits `dcvar_fit`, so
  `rho_trajectory()`, `plot_rho()`, and `loo()` work unchanged) with new
  extractors `phi_trajectory()` and `sigma_trajectory()` (flag-agnostic:
  constants are tiled over time), plots `plot_phi_trajectory()` /
  `plot_sigma_trajectory()`, `fitted()`/`predict()` using the per-time
  coefficients and scales, per-time plug-in PIT values, and per-time
  spectral-radius monitoring in the Stan generated quantities.
- `simulate_dcvar()` gains optional `phi_trajectory` and `sigma_trajectory`
  arguments (matrix, list of per-coefficient vectors — the `rho_*`
  generators can be reused — or constants). The marginal quantile transform
  is now scale-aware, so exponential/gamma dimensions can be simulated with
  any constant scale; regression tests pin the copula orientation under
  time-varying scales for every `skew_direction` combination.
- Time-varying scales (`tv_sigma`) apply to **all** margin families. Normal
  and skew-normal dimensions use a multiplicative log-scale random walk;
  exponential and gamma dimensions use a **soft-barrier** transform
  `x = softplus_k(m_t + skew * eps)` (sharpness `tv_sigma_k`, default 8) so
  the scale `m_t` can vary freely without the hard support boundary coupling
  it to the residuals. The soft-barrier matches the exact shifted margin in
  the interior and rounds the boundary smoothly (a small residual-mean bias
  in the lower tail; larger `tv_sigma_k` tightens it at the cost of stiffer
  geometry). `simulate_dcvar()` gains `tv_sigma_k` to generate matching data
  for an exp/gamma time-varying-scale fit.
- In the generic TV model `shape_gam` is per-dimension (mixed-model
  convention), unlike the shared scalar in the specialised gamma models.
  `dcvar_compare()` warns when a TV fit is compared against less heavily
  latent-conditioned fits.

# dcvar 0.4.0

## Breaking / scientifically relevant fixes

- **Simulators no longer negate the dependence for left-skewed margins.**
  The Stan likelihoods treat the copula uniform on a `skew_direction = -1`
  exponential/gamma dimension as `u = 1 - F(x_shifted)`, but `simulate_dcvar()`
  (and the shared mixed-margin helper used by `simulate_dcvar_multilevel()` and
  `simulate_dcvar_sem()`, plus the homogeneous exponential SEM path) negated
  the quantile-transformed variable *after* applying the copula. Data simulated
  with exactly one negative `skew_direction` therefore implied copula
  correlation `-rho` while `true_params` recorded `+rho`, so simulate-then-fit
  studies silently recovered the negated dependence trajectory. Simulations
  that used `c(1, 1)` or `c(-1, -1)` are unaffected (the flips cancel); any
  results generated with asymmetric skew directions should be re-run.
- The `eps_rep` posterior-predictive blocks in seven Stan models had the
  mirror-image inversion bug and replicated negated dependence on left-skewed
  dimensions; they now invert at the flipped uniform.
- `dependence_summary()` for HMM fits now averages Kendall's tau over states
  per draw (`sum_k gamma[t,k] * (2/pi) asin(rho_state[k])`) instead of applying
  `asin` to the gamma-weighted mean rho, which understated tau during regime
  transitions.
- `hmm_states()$viterbi` is now a genuine Viterbi (MAP) decoding on
  posterior-mean emission/transition log-probabilities. The previous
  most-frequent-sampled-path estimator degenerated to an arbitrary
  (lexicographically first) single draw's path whenever parameter uncertainty
  made nearly all sampled paths unique.
- HMM posterior predictive replicates (`eps_rep`) are now drawn from the
  regime mixture (a state sampled from the smoothed probabilities, then that
  state's rho) instead of the gamma-weighted mean rho.
- `.relative_bias()` (used by `compute_rho_metrics()` /
  `compute_param_metrics()`) now normalizes the mean error by the mean true
  value (by the mean absolute true value for mixed-sign trajectories, which
  preserves the conventional sign for negative parameters). The previous
  pointwise form exploded to ~1e12 % when any true value was near zero
  (e.g. null-dependence conditions), silently corrupting aggregated
  summaries. It returns `NA` with a warning when all true values are near
  zero, and `aggregate_metrics()` now tolerates that `NA` (its summaries
  already used `na.rm = TRUE`).

## Bug fixes

- `hmm_EG.stan` now exposes `sigma_exp` (plus `b_gq` and `rate_exp`) as
  saved generated quantities. Previously they were brace-local, so
  `summary()`, `var_params()`, `coef()`, and `plot_diagnostics()` errored and
  `pit_values()` silently returned all-NA for exponential-margin HMM fits.
- Tibble input no longer breaks multilevel fits: per-unit time-grid
  validation was silently skipped and the stored time axis corrupted, crashing
  `rho_trajectory()`, `fitted()`, and `predict()` downstream. All preparation
  functions now coerce to a plain data frame up front.
- Character and unordered-factor time columns are now rejected: they sort
  lexicographically ("T10" before "T2"), silently scrambling the VAR(1)
  ordering while making the spacing checks vacuous.
- Leading/trailing runs of two or more missing rows are now treated as edge
  trims rather than adjacency-breaking interior gaps, so they no longer abort
  (or warn misleadingly) when removing them preserves adjacency.
- `loo()` and `dcvar_compare()` now support all multilevel fits:
  `multilevel_copula_var.stan` stores per-observation `log_lik` like its EG
  and mixed siblings, and the margin-based whitelist was removed.
  `dcvar_compare()` warns when an HMM fit (state-marginalized predictive
  density) is compared against a dynamic fit (conditioned on the smoothed
  latent rho trajectory), which can systematically favor the dynamic model.
- The `seed` argument now makes fits reproducible: default per-chain initial
  values are generated under a deterministic RNG (previously they came from
  the unseeded global R RNG, so two fits with the same seed differed).
- cmdstanr fits now survive `saveRDS()` and an R restart: posterior draws are
  eagerly read into the fit object after sampling instead of being lazily
  re-read from CSVs in the session tempdir.
- `interpret_rho_trajectory()` no longer errors on Clayton constant fits; it
  interprets the dependence via Kendall's tau.
- The Clayton copula log-density is computed in log space, avoiding overflow
  to `-Inf` (with NaN gradients) for `theta` greater than about 34 during
  warmup.
- PIT helpers abort with a clear message when a margin parameter group is
  missing from the Stan output instead of silently returning all-NA values.
- `simulate_dcvar_sem(n_time = 1)` no longer crashes with a subscript error;
  `prepare_multilevel_data()` requires at least 3 occasions per unit;
  `.safe_cor()` handles length-1 inputs; `Y[cc, ]` row removal keeps the
  matrix shape with a single remaining row.
- `print()` for constant-fit summaries no longer swaps the CI bounds when
  `probs` are not passed in ascending order.
- `draws()` validates its `format` argument instead of silently returning a
  `draws_array`.
- Divergence/treedepth counts are reported as `NA` (unknown) rather than 0
  for fits without sampler diagnostics.
- `plot_hmm_states()` pins the state factor levels so Viterbi point colors
  match the fill colors when the MAP path skips a state;
  `plot_trajectories()` forwards `...` only to the scenario generators that
  accept each argument.
- Warnings are emitted for prior arguments that a configuration ignores
  (`prior_sigma_eps_rate` with no normal margin; `prior_z_rho_sd` with the
  Clayton copula; `prior_sigma_omega_rate` and `zero_init_eta` with
  `dcvar_covariate(drift = FALSE)`), and the recorded `priors` list omits
  unused entries.
- `interpret_rho_trajectory()` classifies Clayton dependence strength on the
  rho-equivalent scale (`sin(pi * tau / 2)`), so the labels are comparable
  with the Gaussian branch for equivalent dependence.
- Per-chain init seeds are derived in double arithmetic, so seeds near
  `.Machine$integer.max` no longer overflow and abort the fit.

## Validation

- All bivariate Stan models now declare `int<lower=2, upper=2> D`, rejecting
  D > 2 data that the hard-wired bivariate copula code would silently
  mishandle.

## Documentation

- Documented the plug-in nature of `predict()` intervals, the raw-data scale
  of simulator `true_params` (fit with `standardize = FALSE` for round-trip
  comparisons), the lognormal scale prior for exponential/gamma multilevel
  margins, and `prior_rho_init_sd` as the covariate-model dependence
  intercept (`beta_0`) prior.
- Added the covariate model family to the README table and the pkgdown
  reference index (which previously failed to build due to missing topics).

## Tests

- New regression tests pin the simulator copula orientation for every
  `skew_direction` combination, seed reproducibility, tibble input, time
  column validation, and edge-gap handling. The Clayton-normal constant model
  and `dcvar_covariate()` (drift and no-drift) now get real MCMC smoke fits
  in CI.

# dcvar 0.3.1

## Bug fixes

- `summary()` printouts for HMM and multilevel fits now include the marginal
  scale/shape parameters (e.g. `sigma_exp`, `omega`, `delta`, `sigma_gam`,
  `shape_gam`) for non-normal and per-variable (mixed) margins. Previously the
  HMM summary omitted all margin scale parameters, and the multilevel summary
  dropped them for mixed margins.
- `simulate_breakpoint_data()` now records the breakpoint specification
  (`type`, plus `breakpoint` or `breakpoints`) in `true_params`, so the
  documented access no longer returns `NULL`.

## Validation

- `rho_decreasing()` and `rho_increasing()` now validate that `rho_start` and
  `rho_end` are single finite values in `[-1, 1]`, matching the other rho
  trajectory generators.

## Documentation

- Extensive roxygen, vignette, README, and CITATION updates so the
  documentation reflects per-variable (mixed) margin support across all model
  families (including the Clayton-copula constant model) and the correct
  `coef()` / `fitted()` / data-preparation contracts.

## Internal

- Removed unused helper code, made the exponential-margin diagnostic generated
  quantity (`b_gq`) report the clamped lower bound consistently across the
  exponential models (inference-neutral), and corrected Stan prior-hyperparameter
  comments. The Clayton-normal constant model's `sigma_eps` prior is left
  unchanged and its intentional divergence from the other constant models is now
  documented.

# dcvar 0.3.0

## Per-variable (mixed) margins

- All copula VAR model families now accept a length-2 `margins` vector so each
  variable can use its own marginal family, e.g.
  `margins = c("normal", "exponential")`. This exploits the copula's separation
  of the marginal distributions from the dependence structure. Supported across
  `dcvar_constant()`, `dcvar()`, `dcvar_hmm()`, `dcvar_multilevel()`, and
  `dcvar_sem()` (both the indicator and naive methods).
- Added generic mixed-margins Stan models that dispatch each dimension to its
  own marginal family and apply the copula on the CDF scale:
  `constant_mixed.stan`, `dcvar_mixed_ncp.stan`, `hmm_mixed.stan`,
  `multilevel_mixed.stan`, `sem_mixed.stan`, and `sem_naive_mixed.stan`.
- Mixed margins are also available with the **Clayton** copula for the constant
  model (`constant_mixed_clayton.stan`), previously limited to normal margins.
- `simulate_dcvar()`, `simulate_dcvar_multilevel()`, and `simulate_dcvar_sem()`
  accept the same per-variable `margins` vector so mixed-family data can be
  generated (for example for parameter-recovery studies).
- `coef()`, `var_params()`, `pit_values()`, and the diagnostics/plots report
  each dimension under its own family for mixed fits across all model families.

## Backward compatibility

- A single `margins` string is unchanged, and an all-identical `margins` vector
  (such as `c("normal", "normal")`) routes to the existing specialised
  single-family model, so prior results, tests, and the gamma shared-shape
  parameterisation are preserved exactly.
- The mixed multilevel and SEM models support all four families per dimension.
  Single-family multilevel and SEM fits keep their existing
  normal/exponential-only restriction (there is no specialised gamma or
  skew-normal model for those structures); request the other families through a
  per-variable `margins` vector instead.

# dcvar 0.2.0

## Simulation model parity

- Added a constant Clayton-copula DC-VAR for normal margins via
  `dcvar_constant(copula = "clayton")`.
- Added exponential-margin support for `dcvar_multilevel()`.
- Added naive SEM score models via `dcvar_sem(method = "naive")` for normal
  and exponential margins.
- Added `dependence_summary()` for Kendall's tau summaries across Gaussian and
  Clayton copula fits.

## Infrastructure

- Added copula-family dispatch alongside the existing margin dispatch.
- Added bundled Stan models for the new Clayton, multilevel exponential, and
  naive SEM variants.
- Updated extractors, summaries, diagnostics, LOO support, and tests for the
  new model variants.

# dcvar 0.1.0

## Scope and documentation

- Clarified that the package currently implements Gaussian-copula models only.
- Marked the multilevel and SEM variants as experimental extensions with
  narrower diagnostic support than the core single-level models.
- Documented PIT diagnostics as posterior-mean plug-in diagnostics and made the
  unsupported multilevel and SEM paths explicit in the help pages.
- Clarified the current scope of `loo()` support across model classes.

## Build and submission hygiene

- Excluded local `*-test-local.log` artifacts from source builds.
- Added package citation metadata.

## Testing

- Added skew-normal fit coverage for `dcvar()` and `dcvar_hmm()`.
- Added PIT smoke coverage for gamma and skew-normal margins.
