Data Contracts
This page describes the data contracts the SPC library expects from callers: which .NET types are accepted, how observations must be ordered, how subgroups are represented, and what the library does when input data is missing, invalid, or too small to support a statistically meaningful result.
Understanding these contracts before calling any chart or capability API prevents the most common runtime exceptions and ensures that the resulting charts reflect the true process.
Supported Input Types
All SPC entry points accept numeric data through one of three .NET types. Choose the type that matches how your application already holds its data to avoid unnecessary copying.
Type | Typical use case | Notes |
|---|---|---|
Individual measurements, attribute counts, or the flattened values of a variable-subgroup data set. | The preferred type for one-dimensional data. Shares memory with the underlying array when constructed from a double[]; no extra allocation is needed. | |
Equal-sized subgroup data for XBar‑R, XBar‑S, and related charts. Each row is one subgroup. | All rows must have the same number of columns (the subgroup size n). Column-major storage is the library default; row-major matrices are accepted but incur a transposition step. | |
ReadOnlySpan<double> | Stack-allocated or sliced buffer of measurements passed without a heap allocation, for example when reading a segment from a larger array. | Span overloads are available on all IndividualsMovingRangeChartSet and subgroup chart constructors. Internally the data is pinned only for the duration of the computation. |
Ordering Requirements
The library always treats data as if it were collected in time order. The first element of a Vector<T> (index 0) represents the earliest observation, and the last element represents the most recent.
If your data store returns rows in reverse-chronological order (newest first), reverse the collection before constructing the input vector.
Subgroup Representation
The SPC library supports two subgroup layouts: equal-sized subgroups supplied as a matrix, and variable-sized subgroups supplied as a flat vector paired with a subgroup-ID vector.
Equal-Sized Subgroups
Pass a Matrix<T> where each row is one subgroup and every row has the same number of columns. The library derives n from the column count at construction time.
// Subgroups as a Matrix: rows = subgroups, columns = measurements
double[,] data = {
{ 9.8, 10.2, 10.0, 10.1 },
{ 10.3, 9.9, 10.1, 10.2 },
{ 9.7, 10.4, 9.8, 10.0 },
{ 10.1, 10.0, 9.9, 10.3 },
{ 10.2, 9.8, 10.2, 10.1 }
};
Matrix<double> subgroups = Matrix.CopyFrom(data);
XBarRChartSet chart = new XBarRChartSet(subgroups);
chart.Analyze();
Console.WriteLine($"XBar CL = {chart.MeansSeries.CenterLine:F4}");
Console.WriteLine($"XBar UCL = {chart.MeansSeries.UpperControlLimit:F4}");This layout feeds XBarRChartSet and XBarSChartSet directly.
Variable-Sized Subgroups
When subgroups differ in size, pass the measurements as a flat Vector<T> together with an integer vector of subgroup IDs or a vector of subgroup sizes. The library uses the ID vector to partition the flat data into subgroups at analysis time.
// Variable-size subgroups: provide defect counts + sample sizes per subgroup
Vector<double> defects =
Vector.Create(new double[] { 3, 5, 2, 7, 4 });
Vector<double> sampleSizes =
Vector.Create(new double[] { 50, 60, 45, 70, 55 });
PChart chart = new PChart(defects, sampleSizes);
chart.Analyze();
// P chart produces pointwise limits that vary with sample size
Vector<double> upperLimits = chart.Series.UpperControlLimits;
Vector<double> lowerLimits = chart.Series.LowerControlLimits;
Console.WriteLine(
$"UCL[0] = {upperLimits[0]:F4} UCL[4] = {upperLimits[4]:F4}");Individuals and Moving-Range Input
Individuals charts expect a single Vector<T> of measurements. The moving-range chart is computed internally from successive differences; callers do not supply the moving-range values directly.
// Provide observations as a Vector<double>
double[] data = { 9.8, 10.2, 10.0, 9.9, 10.1, 10.3, 9.7, 10.4 };
Vector<double> observations = Vector.Create(data);
IndividualsMovingRangeChartSet chart =
new IndividualsMovingRangeChartSet(observations);
chart.Analyze();
Console.WriteLine(
$"Individuals CL = {chart.IndividualsSeries.CenterLine:F4}");The IndividualsMovingRangeChartSet type holds both the individuals chart data and the moving-range chart data after the analysis completes.
Missing and Invalid Values
The library enforces strict numeric validity. Any observation that is double.NaN, double.PositiveInfinity, or double.NegativeInfinity causes the analysis method to throw an ArgumentException identifying the offending index.
See Diagnostics, Exceptions, and Failure Modes for the full list of exceptions thrown on invalid input and for patterns to validate data before the call.
Minimum Sample Requirements
Control-limit computation requires enough data points to produce a stable within-process sigma estimate. The table below lists the hard minimums enforced by the library; passing fewer observations than the minimum throws an ArgumentException.
Chart family | Minimum input | Reason |
|---|---|---|
Individuals / MR | 2 observations | At least one successive difference is required to estimate the moving range. |
XBar‑R, XBar‑S | 2 subgroups | Grand mean and average range / standard deviation require at least two subgroups. |
P, NP, C, U | 2 subgroups | Center-line estimation requires at least two subgroup totals. |
EWMA, CUSUM | 2 observations | The recursive statistic is defined from the first observation; a second point is required to verify sigma estimation. |
Invalid Input Cases for Attribute Charts
Attribute charts impose additional domain constraints on top of the general numeric-validity rules:
Chart | Invalid condition | Exception |
|---|---|---|
P chart | Any defective count exceeds its subgroup size, or any proportion falls outside [0, 1]. | ArgumentException |
NP chart | Negative defective count, or count exceeds subgroup size. | ArgumentException |
C chart | Negative defect count. | ArgumentException |
U chart | Zero or negative inspection unit, or negative defect count. | ArgumentException |
All variable charts | Subgroup-size vector length differs from the measurement vector or matrix row count. | ArgumentException |