}
if(this.methodUsed==14){
this.linterp = new LinearInterpolation(yy, xx);
}
else{
this.interp = new CubicSpline(yy, xx);
}
// record working curve direction
this.curveDirection = true;
if(this.interpResponseStart>this.interpResponseEnd)this.curveDirection = false;
// revisit working range
this.workingResponseMin = Fmath.minimum(this.calculatedResponses);
if(this.curveDirection){
if(this.workingResponseMin<this.interpResponseStart)this.workingResponseMin = this.interpResponseStart;
}
else{
if(this.workingResponseMin<this.interpResponseEnd)this.workingResponseMin = this.interpResponseEnd;
}
this.workingResponseMax = Fmath.maximum(this.calculatedResponses);
if(this.curveDirection){
if(this.workingResponseMax>this.interpResponseEnd)this.workingResponseMax = this.interpResponseEnd;
}
else{
if(this.workingResponseMax>this.interpResponseStart)this.workingResponseMax = this.interpResponseStart;
}
// Prepare response error concn interpolation data within the working range
double[] ee = new double[this.nWorking];
double yError = Math.sqrt(super.sumOfSquaresError/(this.nAnalyteConcns - super.nParam));
if(this.sampleErrorFlag){
if(!this.weightsEntered){
for(int i=0; i<this.nWorking; i++){
ee[i] = yError;
}
}
else{
// check if weights are monotonic within the working range
boolean monoCheck = true;
int iS = 0;
int iF = this.nAnalyteConcns-1;
boolean breakFlag = false;
if(this.ambigCheck){
for(int i=0; i<this.nAnalyteConcns; i++){
if(this.interpAnalyteStart>=this.analyteConcns[i]){
iS = i;
breakFlag = true;
}
if(breakFlag)break;
}
breakFlag = false;
for(int i=this.nAnalyteConcns-1; i>=0; i--){
if(this.interpAnalyteEnd<=this.analyteConcns[i]){
iF = i;
breakFlag = true;
}
if(breakFlag)break;
}
}
int nwe = iF - iS + 1;
double[] ew = new double[nwe];
for(int i=0; i<nwe; i++)ew[i] = this.weights[i+iS];
monoCheck = ImmunoAssay.isMonotonic(ew);
// check for big jumps in the weights
if(monoCheck){
double gap1 = Math.abs(ew[1] - ew[0]);
double gap0 = gap1;
for(int i=2; i<nwe; i++){
gap1 = Math.abs(ew[i] - ew[i-1]);
if(gap1>gap0)gap0 = gap1;
}
if(gap0>0.6*Math.abs(Fmath.maximum(ew) - Fmath.minimum(ew)))monoCheck = false;
}
// scale weights to overall fitting variance
double[] sWeights = new double[this.nAnalyteConcns];
double scale = yError/this.weightsMean;
for(int i=0; i<this.nAnalyteConcns; i++)sWeights[i] = weights[i]*scale;
if(this.weightsEntered && !monoCheck){
// linear interpolation if weights are non-monotonic or have big jumps
LinearInterpolation liee = new LinearInterpolation(this.analyteConcns, sWeights);
for(int i=0; i<this.nWorking; i++)ee[i] = Math.abs(liee.interpolate(xx[i]));
}
else{
// cubic spline interpolation if weights are monotonic without big jumps
CubicSpline csee = new CubicSpline(this.analyteConcns, sWeights);
for(int i=0; i<this.nWorking; i++)ee[i] = Math.abs(csee.interpolate(xx[i]));
}
}
this.errorp = new CubicSpline(yy, ee);
// Calculate the estimated errors in the estimated concentrations for each of the data points
this.propagatedErrors = new String[this.nAnalyteConcns];
double temp = 0.0;
ArrayList<Double> alpe = new ArrayList<Double>();
for(int i=0; i<this.nAnalyteConcns; i++){
boolean checkFlag2 = false;
if(this.curveDirection){
if(this.responses[i]<this.interpResponseStart || this.responses[i]>this.interpResponseEnd)checkFlag2 = true;
}
else{
if(this.responses[i]>this.interpResponseStart || this.responses[i]<this.interpResponseEnd)checkFlag2 = true;
}
if(checkFlag2){
this.propagatedErrors[i] = "**";
}
else{
alpe.add(new Double(this.responses[i]));
temp = this.getSampleConcn(this.responses[i]);
temp = this.getSampleConcnError();
alpe.add(new Double(temp));
temp = Fmath.truncate(temp, super.prec);
this.propagatedErrors[i] = (new Double(temp)).toString();
}
}
// Calculate minimum, maximum and mean propagated errors
int npe = alpe.size()/2;
double[] resp = new double[npe];
double[] xerr = new double[npe];
for(int i=0; i<npe; i++){
resp[i] = (alpe.get(2*i)).doubleValue();
xerr[i] = (alpe.get(2*i+1)).doubleValue();
}
CubicSpline cspe = new CubicSpline(resp, xerr);
double[] respe = new double[1001];
double[] xerre = new double[1001];
respe[0] = resp[0];
respe[1000] = resp[npe-1];
double incr = (resp[npe-1] - resp[0])/1000;
for(int i=1; i<1000; i++){
respe[i] = respe[i-1] + incr;
}
for(int i=0; i<1001; i++){
xerre[i] = cspe.interpolate(respe[i]);
}
Stat stat = new Stat(xerre);
this.minimumAerror = stat.minimum();
this.maximumAerror = stat.maximum();
this.meanAerror = stat.mean();