private static double[] computeCoefficients(double x, double[] xval, double[] yval, double[] robustnessWeights, int[] bandwidthInterval)
{
int iLeft = bandwidthInterval[0];
int iRight = bandwidthInterval[1];
// Compute the point of the bandwidth interval that is
// farthest from x
int edge = (x - xval[iLeft] > xval[iRight] - x) ? iLeft : iRight;
// Compute a least-squares linear fit weighted by
// the product of robustness weights and the tricube
// weight function.
// See http://en.wikipedia.org/wiki/Linear_regression
// (section "Univariate linear case")
// and http://en.wikipedia.org/wiki/Weighted_least_squares
// (section "Weighted least squares")
double sumWeights = 0;
double sumX = 0, sumXSquared = 0, sumY = 0, sumXY = 0;
double denom = Math.Abs(1.0 / (xval[edge] - x));
for (int k = iLeft; k <= iRight; ++k)
{
double xk = xval[k];
double yk = yval[k];
double dist = Math.Abs(x - xk);
double robustnessWeight = robustnessWeights == null ? 1.0 : robustnessWeights[k];
double w = tricube(dist * denom) * robustnessWeight;
double xkw = xk * w;
sumWeights += w;
sumX += xkw;
sumXSquared += xk * xkw;
sumY += yk * w;
sumXY += yk * xkw;
}
double meanX = sumX / sumWeights;
double meanY = sumY / sumWeights;
double meanXY = sumXY / sumWeights;
double meanXSquared = sumXSquared / sumWeights;
double beta;
if (meanXSquared == meanX * meanX)
{
beta = 0;
}
else
{
beta = (meanXY - meanX * meanY) / (meanXSquared - meanX * meanX);
}
double alpha = meanY - beta * meanX;
return new double[] { alpha, beta };
}