Added some confidence by datacount calculations to angle cluster polar service

This commit is contained in:
Frederik Petersen committed 2015-05-28 15:48:26 +02:00
1 parent 97e7a9d183
commit e62091996e
2 files changed
+32 -6

No files matched your search

@@ -326,8 +326,14 @@ public class PolarDataMiner {
SpeedWithConfidence<Void> speedWithConfidence;
try {
int convertedAngle = convertAngleIfNecessary(angle);
speedWithConfidence = speedRegressionPerAngleClusterProcessor.estimateBoatSpeed(boatClass,
SpeedWithConfidence<Void> regressionResult = speedRegressionPerAngleClusterProcessor.estimateBoatSpeed(boatClass,
new KnotSpeedImpl(windSpeed), new DegreeBearingImpl(convertedAngle));
if (regressionResult.getConfidence() > 0.1) {
speedWithConfidence = regressionResult;
} else {
// Low confidence. So put in 0 speed for chart
speedWithConfidence = new SpeedWithConfidenceImpl<Void>(new KnotSpeedImpl(0), regressionResult.getConfidence(), null);
}
} catch (NotEnoughDataHasBeenAddedException e) {
// No data so put in a 0 speed with 0 confidence
speedWithConfidence = new SpeedWithConfidenceImpl<Void>(new KnotSpeedImpl(0), 0, null);
@@ -29,6 +29,8 @@ public class SpeedRegressionPerAngleClusterProcessor implements Processor<Groupe
private static final Logger logger = Logger.getLogger(CubicRegressionPerCourseProcessor.class.getName());
private final Map<GroupKey, IncrementalLeastSquares> regressions = new HashMap<>();
private final Map<BoatClass, Long> fixCountPerBoatClass = new HashMap<>();
private final ClusterGroup<Bearing> angleClusterGroup;
@@ -46,6 +48,13 @@ public class SpeedRegressionPerAngleClusterProcessor implements Processor<Groupe
public void processElement(GroupedDataEntry<GPSFixMovingWithPolarContext> element) {
GroupKey key = element.getKey();
IncrementalLeastSquares regression;
BoatClass boatClass = element.getDataEntry().getBoatClass();
synchronized (fixCountPerBoatClass) {
if (!fixCountPerBoatClass.containsKey(boatClass)) {
fixCountPerBoatClass.put(boatClass, 0L);
}
fixCountPerBoatClass.put(boatClass, fixCountPerBoatClass.get(boatClass) + 1);
}
synchronized (regressions) {
regression = regressions.get(key);
if (regression == null) {
@@ -66,18 +75,29 @@ public class SpeedRegressionPerAngleClusterProcessor implements Processor<Groupe
public SpeedWithConfidence<Void> estimateBoatSpeed(BoatClass boatClass, Speed windSpeed, Bearing trueWindAngle) throws NotEnoughDataHasBeenAddedException {
double speedSum = 0;
double numberOfSpeeds = 0;
for (int i = -5; i <= 5; i++) {
long fixCount = 0;
for (int i = -2; i <= 2; i++) {
GroupKey key = createGroupKey(boatClass, new DegreeBearingImpl(Math.abs(trueWindAngle.getDegrees()) + i));
if (regressions.containsKey(key)) {
speedSum += regressions.get(key).getOrCreatePolynomialFunction().value(windSpeed.getKnots());
numberOfSpeeds++;
IncrementalLeastSquares incrementalLeastSquares = regressions.get(key);
fixCount = fixCount + incrementalLeastSquares.getNumberOfAddedPoints();
if (fixCount > 10) {
speedSum += incrementalLeastSquares.getOrCreatePolynomialFunction().value(windSpeed.getKnots());
numberOfSpeeds++;
}
}
}
if (numberOfSpeeds < 1) {
fixCount = (long) (fixCount / numberOfSpeeds);
long fixCountOverall = 0;
if (numberOfSpeeds < 2 || fixCount < 10) {
throw new NotEnoughDataHasBeenAddedException("Not enough data has been added to Per Course Regressions");
} else {
synchronized (fixCountPerBoatClass) {
fixCountOverall = fixCountPerBoatClass.get(boatClass);
}
}
Speed speed = new KnotSpeedImpl(speedSum / numberOfSpeeds);
return new SpeedWithConfidenceImpl<Void>(speed, /*FIXME*/ 0.5, null);
return new SpeedWithConfidenceImpl<Void>(speed, Math.min(1, 5.0 * ((double) fixCount / fixCountOverall)), null);
}
private GroupKey createGroupKey(final BoatClass boatClass, final Bearing angle) {