private static double objective(double bandwidth, double[] gcs, double[] counts)
{
double medianY = Utilities.Median(counts);
int minGC = (int)gcs.Min();
int maxGC = (int)gcs.Max();
LoessInterpolator loess = new LoessInterpolator(bandwidth, 0);
// LOESS
double[] normalized = new double[counts.Length];
{
var model = loess.Train(gcs, counts, 1, computeFitted: false);
double[] fittedByGC = model.Predict(Enumerable.Range(minGC, maxGC).Select(i => (double)i));
for (int i = 0; i < normalized.Length; i++)
{
int gc = (int)gcs[i];
normalized[i] = counts[i] - fittedByGC[gc - minGC] + medianY;
}
}
// another LOESS
double[] fitted = new double[counts.Length];
{
var model = loess.Train(gcs, normalized, 1, computeFitted: false);
double[] fittedByGC = model.Predict(Enumerable.Range(minGC, maxGC).Select(i => (double)i));
for (int i = 0; i < fitted.Length; i++)
{
int gc = (int)gcs[i];
fitted[i] = fittedByGC[gc - minGC];
}
}
return Utilities.StandardDeviation(fitted);
}