/// <summary> /// Performs the calibration /// </summary> /// <param name="positions">list of gaze positions in of calibration points in order in which they were presented</param> public async void Calibrate(List <Point> positions) { calibrationPositions = positions; double[] pupilX = new double[positions.Count]; double[] pupilY = new double[positions.Count]; double[] screenX = new double[positions.Count]; double[] screenY = new double[positions.Count]; for (int i = 0; i < positions.Count; i++) { pupilX[i] = positions[i].X; pupilY[i] = positions[i].Y; // remember this indexing exists because the order in which the points are presented is // not the same as they are generated by the loop screenX[i] = calibrationParameters.calibrationPoints[calibrationParameters.calibrationSequence[i].Index].X; screenY[i] = calibrationParameters.calibrationPoints[calibrationParameters.calibrationSequence[i].Index].Y; } // await Task.Run(() => { xInterpolator = RBF2D.SearchHyperparameters(pupilX, pupilY, screenX, calibrationParameters.baseRadiusRange, calibrationParameters.numBaseRadii, calibrationParameters.numLayersRange, calibrationParameters.regularizerRange, calibrationParameters.numRegularizers, calibrationParameters.logSpaceRegularizers); yInterpolator = RBF2D.SearchHyperparameters(pupilX, pupilY, screenY, calibrationParameters.baseRadiusRange, calibrationParameters.numBaseRadii, calibrationParameters.numLayersRange, calibrationParameters.regularizerRange, calibrationParameters.numRegularizers, calibrationParameters.logSpaceRegularizers); }); OnCalibrationFinished(); }
public RBF2DTo2D(double[] x, double[] y, double[] valueX, double[] valueY) { xInterpolator = new RBF2D(x, y, valueX); yInterpolator = new RBF2D(x, y, valueY); dataX = x; dataY = y; dataValueX = valueX; dataValueY = valueY; }
/// <summary> /// Performs leave-one-out selection of best hyperparameter values for the RBF /// </summary> /// <param name="x">data X</param> /// <param name="y">data Y</param> /// <param name="value">data values at (X, Y)</param> /// <param name="baseRadiusRange">range of values for the base radius, must > 0</param> /// <param name="numBaseRadii">number of values for the base radius</param> /// <param name="numLayersRange">number of layers, must be > 0</param> /// <param name="regularizerRange">range of regularizers to use, must be >= 0</param> /// <param name="numRegularizers">number of regularizers</param> /// <param name="logSpaceRegularizers">log space instead of linearly space regularizers?</param> /// <returns>RBF fit on all of the data using the parameter that generated the lowest sum of squares loss</returns> public static RBF2D SearchHyperparameters(double[] x, double[] y, double[] value, Tuple <double, double> baseRadiusRange, int numBaseRadii, Tuple <int, int> numLayersRange, Tuple <double, double> regularizerRange, int numRegularizers, bool logSpaceRegularizers) { RBF2D best = null; double bestError = Double.PositiveInfinity; List <double> regularizers = new List <double> { regularizerRange.Item1 }; double start = regularizerRange.Item1; double end = regularizerRange.Item2; if (logSpaceRegularizers) { start = start == 0 ? -6 : Math.Log(start); end = Math.Log(end); } foreach (double regularizer in Num.linspace(start, end, regularizerRange.Item1 == 0 ? numRegularizers - 1 : numRegularizers)) { regularizers.Add(logSpaceRegularizers ? Math.Pow(10, regularizer) : regularizer); } object parallelLock = new object(); foreach (double baseRadius in Num.linspace(baseRadiusRange.Item1, baseRadiusRange.Item2, numBaseRadii)) { for (int numLayers = numLayersRange.Item1; numLayers < numLayersRange.Item2 + 1; numLayers++) { Parallel.ForEach(regularizers, (double regularizer) => { RBF2D RBF = new RBF2D(x, y, value) { baseRadius = baseRadius, numLayers = numLayers, regularizer = regularizer }; double error = RBF.CrossValidate(); lock (parallelLock) { if (error < bestError) { best = RBF; bestError = error; } } }); } } return(best); }
public RBF2DTo2D() { xInterpolator = new RBF2D(); yInterpolator = new RBF2D(); }