---
title: "Monitoring multivariate processes with IQCC"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Monitoring multivariate processes with IQCC}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 7,
  fig.height = 5
)
library(IQCC)
```

## Scope

Multivariate process monitoring separates two questions that are often mixed in
practice. Hotelling T-squared charts monitor shifts in a process mean vector,
while generalized-variance and trace charts monitor changes in the covariance
structure. IQCC contains all three workflows:

| Question | Statistic | Main functions |
|:--|:--|:--|
| Has the mean vector shifted? | Hotelling T-squared | `T2.1()`, `T2.2()`, `cchart.T2.1()`, `cchart.T2.2()` |
| Has total generalized variance changed? | `|S|` | `gv_stat()`, `gv_limits()`, `gv_alpha_risk()`, `cchart.GV()` |
| Has standardized covariance structure changed? | `tr(V)` | `trv_stat()`, `trv_limits()`, `trv_alpha_risk()`, `cchart.trV()` |

The covariance charts are complementary. The determinant `|S|` summarizes the
volume of the subgroup covariance matrix. The trace statistic
`(n - 1) tr(Sigma0^-1 S)` can change even when the determinant is nearly
unchanged.

## Input formats

The generalized-variance and trace-statistic functions use the multivariate
subgroup formats accepted by `gv_stat()` and `cchart.GV()`: a list of subgroup
matrices, a subgroup-by-observation-by-variable array, or a stacked matrix with
the subgroup size supplied separately. The examples below use a list because it
makes the subgroup boundaries explicit.

```{r subgroup-data}
g1 <- cbind(
  x = c(-1, 0, 1, -1, 1),
  y = c(-1, 1, 0, 1, -1)
)
g2 <- sweep(g1, 2, c(0.2, -0.1), "+")
g3 <- g1 %*% matrix(c(1.1, 0.1, 0, 0.9), nrow = 2)
groups <- list(g1, g2, g3)

data.frame(
  subgroup = seq_along(groups),
  generalized_variance = gv_stat(groups),
  trace_statistic = trv_stat(groups, Sigma0 = diag(2))
)
```

The legacy Hotelling helpers use a different array convention:
observation-by-variable-by-subgroup. Check `dim()` before moving data between
the Hotelling helpers and the generalized-variance or trace workflows.

## Hotelling T-squared

The Hotelling workflow estimates Phase I location and covariance, computes
Phase I T-squared statistics, and then evaluates Phase II observations against
the Phase II reference distribution.

```{r hotelling-workflow}
set.seed(2026)
phase1 <- data.1(m = 8, n = 5, mu = c(0, 0), Sigma = diag(2))
reference <- IQCC::stats(phase1, m = 8, n = 5, p = 2)
t2_phase1 <- T2.1(reference, m = 8, n = 5)

phase2 <- data.2(reference, n = 5, p = 2)
t2_phase2 <- T2.2(phase2, reference, n = 5)

data.frame(
  phase = c(rep("Phase I", length(t2_phase1)), "Phase II"),
  statistic = c(t2_phase1, t2_phase2)
)
```

`cchart.T2.1()` and `cchart.T2.2()` draw the two chart types. Their control
limits are not interchangeable because Phase I and Phase II use different
reference distributions.

## Generalized variance

For each subgroup, `gv_stat()` computes the determinant of the sample
covariance matrix. `gv_limits()` exposes normal, Cornish-Fisher, selected exact,
and simulation-based limits. The exact implementation is deliberately scoped;
generic Meijer-G quantiles are not claimed by the package.

```{r gv-limits}
gv_methods <- do.call(
  rbind,
  lapply(c("normal", "cf", "exact"), function(method) {
    limits <- gv_limits(n = 5, p = 2, det_sigma = 1, type = method)
    data.frame(
      method = method,
      center = limits$center,
      lcl = limits$lcl,
      ucl = limits$ucl
    )
  })
)

gv_sim <- gv_limits(
  n = 5,
  p = 2,
  det_sigma = 1,
  type = "simulation",
  nsim = 2000,
  seed = 2026
)

gv_methods
gv_sim[c("type", "ucl", "nsim", "seed")]
```

The chart wrapper records the phase split, limits, covariance source, and
signaled subgroups. Use `summary()` to inspect the fitted object instead of
reading values from a plot.

```{r gv-chart}
gv_chart <- cchart.GV(
  x1 = groups[1:2],
  x2 = groups[3],
  type = "cf",
  plot = FALSE
)
summary(gv_chart)
```

If `Sigma` is omitted, IQCC uses Phase I covariance information as a plug-in
reference. The nominal known-parameter calibration does not include the extra
uncertainty introduced by estimating the reference from a finite Phase I sample.

## Auxiliary trace chart

The trace statistic is

\[
T = (n - 1)\operatorname{tr}(\Sigma_0^{-1} S).
\]

Under multivariate normality and known in-control covariance `Sigma0`,
`T` has a chi-square distribution with `p * (n - 1)` degrees of freedom.

```{r trv-limits}
trv_limits(n = 5, p = 2, alpha = 0.0027)
trv_alpha_risk(n = 5, p = 2, ucl = trv_limits(5, 2)$ucl)
```

The trace chart is most useful beside `|S|`, not as a replacement for it. The
following deterministic example has two covariance matrices with the same
determinant but different standardized trace.

```{r same-determinant}
base <- sqrt(3 / 4) * rbind(
  c(1, 1), c(1, -1), c(-1, 1), c(-1, -1)
)
same_volume <- list(
  base %*% chol(diag(2)),
  base %*% chol(diag(c(4, 0.25)))
)

data.frame(
  generalized_variance = gv_stat(same_volume),
  trace_statistic = trv_stat(same_volume, Sigma0 = diag(2))
)
```

```{r trv-chart}
trv_chart <- cchart.trV(
  x = same_volume[1],
  newdata = same_volume[2],
  Sigma0 = diag(2),
  alpha = 0.05,
  type = "chisq",
  plot = FALSE
)
summary(trv_chart)
```

The published generalized-variance report contains a Case B where the printed
summary matrices keep determinants close while the trace chart signals in Phase
II. IQCC reproduces the printed determinants and the published trace UCL, but
the full signal sequence cannot be recomputed because the report does not print
all simulated subgroups or the random seed.

## Practical sequence

1. Use Hotelling T-squared when the primary question is a shift in the mean
   vector.
2. Use `|S|` when the primary question is a change in generalized variance or
   covariance volume.
3. Add `tr(V)` when covariance structure may change without a large determinant
   change.
4. State whether covariance references are known parameters or Phase I plug-in
   estimates.
5. Use simulated limits as Monte Carlo approximations and report `nsim`, `seed`,
   and simulation error when they support a scientific claim.

```{r execution-marker, results='asis'}
cat("<!-- IQCC_EXECUTED_MULTIVARIATE_MONITORING -->\n")
```
