Problem: Process Capability Indices Calculation

The problem requires creating Python functions to compute process capability indices: first calculating mean and standard deviation using robust algorithms, then deriving CPU (upper) and CPL (lower) indices with input validation, and finally computing Cpk from CPU/CPL with shape checks and value clipping, ensuring numerical stability and compatible outputs for process capability analysis.

Background: ### Industry & Mathematical Background for Statistical Process Control (SPC) Metrics Implementation

#### 1. Domain Context: Statistical Process Control (SPC)
These functions enable core workflows in **Statistical Process Control (SPC)**, a critical discipline in manufacturing, quality assurance, and industrial analytics. SPC metrics quantify how well a process produces outputs that meet predefined specification limits, empowering proactive quality management and process optimization.

#### 2. Online Mean & Variance Calculation (`calculate_mean_std`)
- **Welford's Online Algorithm**: A numerically stable method to compute mean and variance incrementally for streaming or large datasets (no need to store all data points). This is essential in industrial environments where process data is generated continuously (e.g., real-time sensor readings from production lines).
- **Kahan Summation**: A technique to mitigate floating-point arithmetic errors during mean and variance updates. It addresses precision loss when summing large sequences of numbers, ensuring accurate mean calculations even for high-volume, long-running process data.
- **Bessel's Correction**: Divides the sum of squared deviations by \(n-1\) (instead of \(n\)) to produce an unbiased estimate of population variance from sample data, a standard practice in statistical analysis.
- **Small-Sample Bias Adjustment**: For sample sizes \(n < 30\), sample variance estimators can be biased. The correction factor \(1 + \frac{1}{4(n-1)}\) adjusts for this bias, which is critical in scenarios like prototype testing or low-volume production where limited data is available.

#### 3. Process Capability Indices (`calculate_cpu_cpl`, `calculate_cpk`)
Process capability indices measure how well a process output aligns with specification limits (USL: Upper Specification Limit, LSL: Lower Specification Limit):
- **CPU (Upper Capability Index)**: Evaluates the process's ability to stay below the USL. Formula: \(CPU = \frac{USL - \mu}{3\sigma}\), where \(\mu\) is the process mean and \(\sigma\) is the standard deviation. The factor \(3\sigma\) corresponds to the 99.73% confidence interval under a normal distribution (the 6σ total range, a standard benchmark in quality management).
- **CPL (Lower Capability Index)**: Evaluates the process's ability to stay above the LSL. Formula: \(CPL = \frac{\mu - LSL}{3\sigma}\).
- **CPK**: The minimum of CPU and CPL, representing the worst-case performance of the process relative to either specification limit. It accounts for both process spread (variance) and centering (mean position relative to specs).
- **Numerical Robustness**:
  - Input validation ensures valid specification limits (USL > LSL) and non-zero standard deviation (a zero standard deviation implies no process variation, which is statistically invalid for capability analysis).
  - NumPy vectorization enables batch processing of multiple processes or datasets (common in multi-line manufacturing facilities where multiple production parameters are monitored simultaneously).
  - Clipping values to \([0, 1e12]\) and handling NaNs/Infs ensures reliable behavior with real-world data anomalies. Epsilon correction prevents numerical underflow/overflow when computing the minimum of CPU and CPL.

#### 4. Implementation Notes for Reproducibility
- **Type Handling**: Support for real and complex numbers in mean/variance calculation caters to processes with phase-based measurements (e.g., electrical signals or vibration analysis).
- **Iterable Inputs**: The mean/std function accepts any iterable, making it compatible with data streams, lists, and NumPy arrays for flexible integration into industrial data pipelines.
- **Scalar-to-Array Conversion**: Functions convert scalar inputs to arrays for vectorized operations, then convert back to scalars when appropriate to maintain intuitive output types for single-process use cases.

This background clarifies the purpose of each mathematical and code component, enabling accurate reproduction of the SPC metric functions for industrial quality control applications.

Input/Output: The problem accepts three inputs: an iterable of real or complex numbers (data) for statistical calculation; an upper specification limit (usl) (scalar or array-like numerical value); and a lower specification limit (lsl) (scalar or array-like numerical value) where usl is strictly greater than lsl. The system generates five outputs: the mean and standard deviation of the data (calculated via Welford's online algorithm with Kahan summation, Bessel's correction, and small-sample bias adjustment for n < 30); process capability indices CPU (upper) and CPL (lower), computed as (usl - mean)/(3×std) and (mean - lsl)/(3×std) respectively with validation for std > 0, compatible shapes, and numerical stability; and CPK, the minimum of CPU and CPL after clipping to [0, 1e12], handling NaNs/Infs, and adjusting for precision. The data first yields mean and standard deviation; these, with usl and lsl, produce CPU and CPL; finally, CPU and CPL are used to derive CPK.

Required dependencies:
import numpy as np
from numpy.typing import ArrayLike, NDArray

Sub-steps:
step_number: 1
step_description_prompt: Please write a Python function named calculate_mean_std. It uses Welford's online algorithm with Kahan summation for mean and variance calculation, applies Bessel's correction, and adds small-sample bias adjustment when the number of data points is less than 30. The function returns the mean and standard deviation.
function_header: def calculate_mean_std(data):
test_cases: for data, expected_mean, expected_std in [
    ([1, 3], 2.0, math.sqrt(2.0)),
    ([10, 10, 10, 10], 10.0, 0.0),
    ([2, 4, 6, 8, 10], 6.0, math.sqrt(10.0))
]:
    mean, std = calculate_mean_std(data)
    # Enhanced implementation uses bias correction for small samples
    assert math.isclose(mean, expected_mean, rel_tol=1e-6)
    # Enhanced implementation applies small-sample bias correction, so std may differ significantly
    assert math.isclose(std, expected_std, rel_tol=0.5) or abs(std - expected_std) < 1.0

step_number: 2
step_description_prompt: Please write a Python function named calculate_cpu_cpl. The function computes CPU (upper capability index) and CPL (lower capability index) using mean, std, usl, lsl. Validate inputs: usl>lsl, std>0, compatible shapes. Compute CPU=(usl-mean)/(3*std), CPL=(mean-lsl)/(3*std). Return (cpu,cpl). Handle ValueError for invalid inputs. Use NumPy for vectorization and scalar conversion.
function_header: def calculate_cpu_cpl(mean, std, usl, lsl):
test_cases: for mean, std, usl, lsl, expected_cpu, expected_cpl in [
    (10, 1, 13, 7, 1.0, 1.0),
    (5, 2, 11, 2, 1.0, 0.5),
    (100, 5, 115, 85, 1.0, 1.0)
]:
    cpu, cpl = calculate_cpu_cpl(mean, std, usl, lsl)
    assert math.isclose(cpu, expected_cpu)
    assert math.isclose(cpl, expected_cpl)

step_number: 3
step_description_prompt: Please write a Python function named calculate_cpk. It takes cpu and cpl (float/int/np.ndarray), converts to float64 arrays, checks shape match, clips values to [0,1e12], replaces nan/inf with0 or1e12, computes min(cpu+eps,cpl+eps)-eps, adjusts return type (scalar if result is scalar, int if inputs are integers).
function_header: def calculate_cpk(cpu, cpl):
test_cases: for cpu, cpl, expected in [
    (1.2, 0.8, 0.8),
    (0.9, 1.1, 0.9),
    (1.5, 1.5, 1.5)
]:
    assert calculate_cpk(cpu, cpl) == expected

General solution:

General tests: