--- 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("\n") ```