for(int i=0; i<this.nWorking; i++){
xx[i] = this.interpolationConcns[this.interpStartIndex+i];
yy[i] = this.calculatedResponses[this.interpStartIndex+i];
}
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]));