JMSL Chart Programmer’s Guide
Cumulative Probability
If the defect rate is very small there will be long runs when the number of defects is zero. In this situation the CChart and UChart are ineffective. An alternative to defect counts is to measure the time between defects.
If the distribution of defect occurrences is Poisson, then the distribution of times between defects is exponential. Unfortunately the exponential distribution is highly skewed. Nelson suggested transforming to Weibull random variables using the transformation x = y1/3.6.
CumulativeProbability Example
The number of hours between failures is measured. A normal probability plot is constructed from the transformed data. A linear regression to the transformed data is also computed. To fit a regression with the normal probability axis, the regression variable needs to be transformed using the inverse normal cumulative distribution function (Montgomery, Example 6-21, 327).
View code file
 
import com.imsl.chart.*;
import com.imsl.stat.Cdf;
import com.imsl.stat.InvCdf;
import com.imsl.stat.Sort;
import com.imsl.stat.LinearRegression;
 
public class SampleCumulativeProbability extends JFrameChart {
 
static final double timeBetweenFailures[] = {
286, 948, 536, 124, 816, 729, 4, 143, 431, 8, 2837,
596, 81, 227, 603, 492, 1199, 1214, 2831, 96
};
 
static final double ticks[] = {
0.001, 0.005, 0.01, 0.02, 0.05,
0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90,
0.95, 0.98, 0.99, 0.995, 0.999
};
 
public SampleCumulativeProbability() {
Chart chart = getChart();
AxisXY axis = new AxisXY(chart);
double a = ticks[0];
double b = ticks[ticks.length - 1];
chart.getChartTitle().setTitle("Normal Probability Plot");
Axis1D axisX = axis.getAxisX();
axisX.getAxisTitle().setTitle("Transformed Time between failures");
Axis1D axisY = axis.getAxisY();
axisY.getAxisTitle().setTitle("Cummulative Probability");
axisY.setTransform(axis.TRANSFORM_CUSTOM);
Transform transform = new NormalTransform();
axis.getAxisY().setCustomTransform(transform);
axis.getAxisY().setAutoscaleInput(axis.AUTOSCALE_OFF);
axis.getAxisY().setWindow(a, b);
axis.getAxisY().setTextFormat("0.0%");
axis.getAxisY().setTicks(ticks);
axis.getAxisY().getMinorTick().setPaint(false);
 
int n = timeBetweenFailures.length;
double x[] = new double[n];
double y[] = new double[n];
for (int i = 0; i < x.length; i++) {
x[i] = Math.pow(timeBetweenFailures[i], 1.0 / 3.6);
}
Sort.ascending(x);
for (int i = 0; i < x.length; i++) {
y[i] = (double) (i + 0.5) / (double) n;
}
Data data = new Data(axis, x, y);
data.setDataType(Data.DATA_TYPE_MARKER);
data.setMarkerType(Data.MARKER_TYPE_FILLED_CIRCLE);
 
/*
* Compute an plot a regresssion line
*/
LinearRegression lr = new LinearRegression(1, true);
for (int i = 0; i < n; i++) {
lr.update(new double[]{x[i]}, InvCdf.normal(y[i]));
}
double coef[] = lr.getCoefficients();
double lry[] = new double[x.length];
for (int i = 0; i < x.length; i++) {
lry[i] = Cdf.normal(coef[0] + coef[1] * x[i]);
}
Data lrData = new Data(axis, x, lry);
lrData.setDataType(Data.DATA_TYPE_LINE);
lrData.setLineColor(java.awt.Color.blue);
}
 
static class NormalTransform implements Transform {
 
private double scaleA, scaleB;
 
/**
* Initializes the mappings between user and coordinate space.
*/
public void setupMapping(Axis1D axis1d) {
double w[] = axis1d.getWindow();
double t = InvCdf.normal(w[0]);
scaleB = 1.0 / (InvCdf.normal(w[1]) - t);
scaleA = -scaleB * t;
}
 
/**
* Maps a point in [0,1] to a probability.
*/
public double mapUnitToUser(double unit) {
return Cdf.normal((unit - scaleA) / scaleB);
}
 
/**
* Maps a probability to the interval [0,1].
*/
public double mapUserToUnit(double p) {
return scaleA + scaleB * InvCdf.normal(p);
}
}
 
public static void main(String argv[]) {
new SampleCumulativeProbability().setVisible(true);
}
}