aboutsummaryrefslogtreecommitdiffstats
path: root/native/jni/src/proximity_info_state_utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'native/jni/src/proximity_info_state_utils.cpp')
-rw-r--r--native/jni/src/proximity_info_state_utils.cpp187
1 files changed, 81 insertions, 106 deletions
diff --git a/native/jni/src/proximity_info_state_utils.cpp b/native/jni/src/proximity_info_state_utils.cpp
index da3f03deb..f9b69d264 100644
--- a/native/jni/src/proximity_info_state_utils.cpp
+++ b/native/jni/src/proximity_info_state_utils.cpp
@@ -38,7 +38,7 @@ namespace latinime {
return nextStartIndex;
}
-/* static */ int ProximityInfoStateUtils::updateTouchPoints(const int mostCommonKeyWidth,
+/* static */ int ProximityInfoStateUtils::updateTouchPoints(
const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
const int *const inputProximities, const int *const inputXCoordinates,
const int *const inputYCoordinates, const int *const times, const int *const pointerIds,
@@ -106,15 +106,14 @@ namespace latinime {
const float prevAngle = getAngle(
inputXCoordinates[i - 2], inputYCoordinates[i - 2],
inputXCoordinates[i - 1], inputYCoordinates[i - 1]);
- const float currentAngle =
- getAngle(inputXCoordinates[i - 1], inputYCoordinates[i - 1], x, y);
+ const float currentAngle = getAngle(
+ inputXCoordinates[i - 1], inputYCoordinates[i - 1], x, y);
sumAngle += getAngleDiff(prevAngle, currentAngle);
}
- if (pushTouchPoint(mostCommonKeyWidth, proximityInfo, maxPointToKeyLength,
- i, c, x, y, time, isGeometric /* doSampling */,
- i == lastInputIndex, sumAngle, currentNearKeysDistances,
- prevNearKeysDistances, prevPrevNearKeysDistances,
+ if (pushTouchPoint(proximityInfo, maxPointToKeyLength, i, c, x, y, time,
+ isGeometric /* doSampling */, i == lastInputIndex, sumAngle,
+ currentNearKeysDistances, prevNearKeysDistances, prevPrevNearKeysDistances,
sampledInputXs, sampledInputYs, sampledInputTimes, sampledLengthCache,
sampledInputIndice)) {
// Previous point information was popped.
@@ -222,12 +221,13 @@ namespace latinime {
}
/* static */ void ProximityInfoStateUtils::initGeometricDistanceInfos(
- const ProximityInfo *const proximityInfo, const int keyCount, const int sampledInputSize,
+ const ProximityInfo *const proximityInfo, const int sampledInputSize,
const int lastSavedInputSize, const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs,
std::vector<NearKeycodesSet> *SampledNearKeysVector,
std::vector<float> *SampledDistanceCache_G) {
SampledNearKeysVector->resize(sampledInputSize);
+ const int keyCount = proximityInfo->getKeyCount();
SampledDistanceCache_G->resize(sampledInputSize * keyCount);
for (int i = lastSavedInputSize; i < sampledInputSize; ++i) {
(*SampledNearKeysVector)[i].reset();
@@ -275,10 +275,11 @@ namespace latinime {
int duration = 0;
// Calculate velocity by using distances and durations of
- // NUM_POINTS_FOR_SPEED_CALCULATION points for both forward and backward.
- static const int NUM_POINTS_FOR_SPEED_CALCULATION = 2;
- for (int j = index; j < min(inputSize - 1, index + NUM_POINTS_FOR_SPEED_CALCULATION);
- ++j) {
+ // ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION points for both forward and
+ // backward.
+ const int forwardNumPoints = min(inputSize - 1,
+ index + ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION);
+ for (int j = index; j < forwardNumPoints; ++j) {
if (i < sampledInputSize - 1 && j >= (*sampledInputIndice)[i + 1]) {
break;
}
@@ -286,7 +287,9 @@ namespace latinime {
xCoordinates[j + 1], yCoordinates[j + 1]);
duration += times[j + 1] - times[j];
}
- for (int j = index - 1; j >= max(0, index - NUM_POINTS_FOR_SPEED_CALCULATION); --j) {
+ const int backwardNumPoints = max(0,
+ index - ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION);
+ for (int j = index - 1; j >= backwardNumPoints; --j) {
if (i > 0 && j < (*sampledInputIndice)[i - 1]) {
break;
}
@@ -434,9 +437,8 @@ namespace latinime {
// Sampling touch point and pushing information to vectors.
// Returning if previous point is popped or not.
-/* static */ bool ProximityInfoStateUtils::pushTouchPoint(const int mostCommonKeyWidth,
- const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
- const int inputIndex, const int nodeCodePoint, int x, int y,
+/* static */ bool ProximityInfoStateUtils::pushTouchPoint(const ProximityInfo *const proximityInfo,
+ const int maxPointToKeyLength, const int inputIndex, const int nodeCodePoint, int x, int y,
const int time, const bool doSampling, const bool isLastPoint, const float sumAngle,
NearKeysDistanceMap *const currentNearKeysDistances,
const NearKeysDistanceMap *const prevNearKeysDistances,
@@ -444,7 +446,7 @@ namespace latinime {
std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs,
std::vector<int> *sampledInputTimes, std::vector<int> *sampledLengthCache,
std::vector<int> *sampledInputIndice) {
- static const int LAST_POINT_SKIP_DISTANCE_SCALE = 4;
+ const int mostCommonKeyWidth = proximityInfo->getMostCommonKeyWidth();
size_t size = sampledInputXs->size();
bool popped = false;
@@ -465,16 +467,16 @@ namespace latinime {
}
// Check if the last point should be skipped.
if (isLastPoint && size > 0) {
- if (getDistanceInt(x, y, sampledInputXs->back(),
- sampledInputYs->back()) * LAST_POINT_SKIP_DISTANCE_SCALE
- < mostCommonKeyWidth) {
+ if (getDistanceInt(x, y, sampledInputXs->back(), sampledInputYs->back())
+ * ProximityInfoParams::LAST_POINT_SKIP_DISTANCE_SCALE < mostCommonKeyWidth) {
// This point is not used because it's too close to the previous point.
if (DEBUG_GEO_FULL) {
AKLOGI("p0: size = %zd, x = %d, y = %d, lx = %d, ly = %d, dist = %d, "
"width = %d", size, x, y, sampledInputXs->back(),
sampledInputYs->back(), getDistanceInt(
x, y, sampledInputXs->back(), sampledInputYs->back()),
- mostCommonKeyWidth / LAST_POINT_SKIP_DISTANCE_SCALE);
+ mostCommonKeyWidth
+ / ProximityInfoParams::LAST_POINT_SKIP_DISTANCE_SCALE);
}
return popped;
}
@@ -664,35 +666,14 @@ namespace latinime {
const std::vector<float> *const SampledDistanceCache_G,
std::vector<NearKeycodesSet> *SampledNearKeysVector,
std::vector<hash_map_compat<int, float> > *charProbabilities) {
- static const float MIN_PROBABILITY = 0.000001f;
- static const float MAX_SKIP_PROBABILITY = 0.95f;
- static const float SKIP_FIRST_POINT_PROBABILITY = 0.01f;
- static const float SKIP_LAST_POINT_PROBABILITY = 0.1f;
- static const float MIN_SPEED_RATE_FOR_SKIP_PROBABILITY = 0.15f;
- static const float SPEED_WEIGHT_FOR_SKIP_PROBABILITY = 0.9f;
- static const float SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY = 0.6f;
- static const float NEAREST_DISTANCE_WEIGHT = 0.5f;
- static const float NEAREST_DISTANCE_BIAS = 0.5f;
- static const float NEAREST_DISTANCE_WEIGHT_FOR_LAST = 0.6f;
- static const float NEAREST_DISTANCE_BIAS_FOR_LAST = 0.4f;
-
- static const float ANGLE_WEIGHT = 0.90f;
- static const float DEEP_CORNER_ANGLE_THRESHOLD = M_PI_F * 60.0f / 180.0f;
- static const float SKIP_DEEP_CORNER_PROBABILITY = 0.1f;
- static const float CORNER_ANGLE_THRESHOLD = M_PI_F * 30.0f / 180.0f;
- static const float STRAIGHT_ANGLE_THRESHOLD = M_PI_F * 15.0f / 180.0f;
- static const float SKIP_CORNER_PROBABILITY = 0.4f;
- static const float SPEED_MARGIN = 0.1f;
- static const float CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION = 0.0f;
-
charProbabilities->resize(sampledInputSize);
// Calculates probabilities of using a point as a correlated point with the character
// for each point.
for (int i = start; i < sampledInputSize; ++i) {
(*charProbabilities)[i].clear();
- // First, calculates skip probability. Starts form MIN_SKIP_PROBABILITY.
+ // First, calculates skip probability. Starts from MAX_SKIP_PROBABILITY.
// Note that all values that are multiplied to this probability should be in [0.0, 1.0];
- float skipProbability = MAX_SKIP_PROBABILITY;
+ float skipProbability = ProximityInfoParams::MAX_SKIP_PROBABILITY;
const float currentAngle = getPointAngle(sampledInputXs, sampledInputYs, i);
const float speedRate = (*sampledSpeedRates)[i];
@@ -709,78 +690,74 @@ namespace latinime {
}
if (i == 0) {
- skipProbability *= min(1.0f, nearestKeyDistance * NEAREST_DISTANCE_WEIGHT
- + NEAREST_DISTANCE_BIAS);
+ skipProbability *= min(1.0f,
+ nearestKeyDistance * ProximityInfoParams::NEAREST_DISTANCE_WEIGHT
+ + ProximityInfoParams::NEAREST_DISTANCE_BIAS);
// Promote the first point
- skipProbability *= SKIP_FIRST_POINT_PROBABILITY;
+ skipProbability *= ProximityInfoParams::SKIP_FIRST_POINT_PROBABILITY;
} else if (i == sampledInputSize - 1) {
- skipProbability *= min(1.0f, nearestKeyDistance * NEAREST_DISTANCE_WEIGHT_FOR_LAST
- + NEAREST_DISTANCE_BIAS_FOR_LAST);
+ skipProbability *= min(1.0f,
+ nearestKeyDistance * ProximityInfoParams::NEAREST_DISTANCE_WEIGHT_FOR_LAST
+ + ProximityInfoParams::NEAREST_DISTANCE_BIAS_FOR_LAST);
// Promote the last point
- skipProbability *= SKIP_LAST_POINT_PROBABILITY;
+ skipProbability *= ProximityInfoParams::SKIP_LAST_POINT_PROBABILITY;
} else {
// If the current speed is relatively slower than adjacent keys, we promote this point.
- if ((*sampledSpeedRates)[i - 1] - SPEED_MARGIN > speedRate
- && speedRate < (*sampledSpeedRates)[i + 1] - SPEED_MARGIN) {
- if (currentAngle < CORNER_ANGLE_THRESHOLD) {
+ if ((*sampledSpeedRates)[i - 1] - ProximityInfoParams::SPEED_MARGIN > speedRate
+ && speedRate
+ < (*sampledSpeedRates)[i + 1] - ProximityInfoParams::SPEED_MARGIN) {
+ if (currentAngle < ProximityInfoParams::CORNER_ANGLE_THRESHOLD) {
skipProbability *= min(1.0f, speedRate
- * SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY);
+ * ProximityInfoParams::SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY);
} else {
// If the angle is small enough, we promote this point more. (e.g. pit vs put)
- skipProbability *= min(1.0f, speedRate * SPEED_WEIGHT_FOR_SKIP_PROBABILITY
- + MIN_SPEED_RATE_FOR_SKIP_PROBABILITY);
+ skipProbability *= min(1.0f,
+ speedRate * ProximityInfoParams::SPEED_WEIGHT_FOR_SKIP_PROBABILITY
+ + ProximityInfoParams::MIN_SPEED_RATE_FOR_SKIP_PROBABILITY);
}
}
- skipProbability *= min(1.0f, speedRate * nearestKeyDistance *
- NEAREST_DISTANCE_WEIGHT + NEAREST_DISTANCE_BIAS);
+ skipProbability *= min(1.0f,
+ speedRate * nearestKeyDistance * ProximityInfoParams::NEAREST_DISTANCE_WEIGHT
+ + ProximityInfoParams::NEAREST_DISTANCE_BIAS);
// Adjusts skip probability by a rate depending on angle.
// ANGLE_RATE of skipProbability is adjusted by current angle.
- skipProbability *= (M_PI_F - currentAngle) / M_PI_F * ANGLE_WEIGHT
- + (1.0f - ANGLE_WEIGHT);
- if (currentAngle > DEEP_CORNER_ANGLE_THRESHOLD) {
- skipProbability *= SKIP_DEEP_CORNER_PROBABILITY;
+ skipProbability *= (M_PI_F - currentAngle) / M_PI_F * ProximityInfoParams::ANGLE_WEIGHT
+ + (1.0f - ProximityInfoParams::ANGLE_WEIGHT);
+ if (currentAngle > ProximityInfoParams::DEEP_CORNER_ANGLE_THRESHOLD) {
+ skipProbability *= ProximityInfoParams::SKIP_DEEP_CORNER_PROBABILITY;
}
// We assume the angle of this point is the angle for point[i], point[i - 2]
// and point[i - 3]. The reason why we don't use the angle for point[i], point[i - 1]
// and point[i - 2] is this angle can be more affected by the noise.
const float prevAngle = getPointsAngle(sampledInputXs, sampledInputYs, i, i - 2, i - 3);
- if (i >= 3 && prevAngle < STRAIGHT_ANGLE_THRESHOLD
- && currentAngle > CORNER_ANGLE_THRESHOLD) {
- skipProbability *= SKIP_CORNER_PROBABILITY;
+ if (i >= 3 && prevAngle < ProximityInfoParams::STRAIGHT_ANGLE_THRESHOLD
+ && currentAngle > ProximityInfoParams::CORNER_ANGLE_THRESHOLD) {
+ skipProbability *= ProximityInfoParams::SKIP_CORNER_PROBABILITY;
}
}
- // probabilities must be in [0.0, MAX_SKIP_PROBABILITY];
+ // probabilities must be in [0.0, ProximityInfoParams::MAX_SKIP_PROBABILITY];
ASSERT(skipProbability >= 0.0f);
- ASSERT(skipProbability <= MAX_SKIP_PROBABILITY);
+ ASSERT(skipProbability <= ProximityInfoParams::MAX_SKIP_PROBABILITY);
(*charProbabilities)[i][NOT_AN_INDEX] = skipProbability;
// Second, calculates key probabilities by dividing the rest probability
// (1.0f - skipProbability).
const float inputCharProbability = 1.0f - skipProbability;
- // TODO: The variance is critical for accuracy; thus, adjusting these parameter by machine
- // learning or something would be efficient.
- static const float SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION = 0.3f;
- static const float MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION = 0.25f;
- static const float SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION = 0.5f;
- static const float MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION = 0.15f;
- static const float MIN_STANDERD_DIVIATION = 0.37f;
-
const float speedxAngleRate = min(speedRate * currentAngle / M_PI_F
- * SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION,
- MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION);
+ * ProximityInfoParams::SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION,
+ ProximityInfoParams::MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION);
const float speedxNearestKeyDistanceRate = min(speedRate * nearestKeyDistance
- * SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION,
- MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION);
- const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate + MIN_STANDERD_DIVIATION;
+ * ProximityInfoParams::SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION,
+ ProximityInfoParams::MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION);
+ const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate
+ + ProximityInfoParams::MIN_STANDERD_DIVIATION;
ProximityInfoUtils::NormalDistribution
- distribution(CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
- static const float PREV_DISTANCE_WEIGHT = 0.5f;
- static const float NEXT_DISTANCE_WEIGHT = 0.6f;
+ distribution(ProximityInfoParams::CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
// Summing up probability densities of all near keys.
float sumOfProbabilityDensities = 0.0f;
for (int j = 0; j < keyCount; ++j) {
@@ -797,8 +774,9 @@ namespace latinime {
// points because the first touch by the user can be sloppy.
// So we promote the first point if the distance of that point is larger
// than the distance of the next point.
- distance = (distance + nextDistance * NEXT_DISTANCE_WEIGHT)
- / (1.0f + NEXT_DISTANCE_WEIGHT);
+ distance = (distance
+ + nextDistance * ProximityInfoParams::NEXT_DISTANCE_WEIGHT)
+ / (1.0f + ProximityInfoParams::NEXT_DISTANCE_WEIGHT);
}
} else if (i != 0 && i == sampledInputSize - 1) {
// For the first point, weighted average of distances from last point and
@@ -810,8 +788,9 @@ namespace latinime {
// because the last touch by the user can be sloppy. So we promote the
// last point if the distance of that point is larger than the distance of
// the previous point.
- distance = (distance + previousDistance * PREV_DISTANCE_WEIGHT)
- / (1.0f + PREV_DISTANCE_WEIGHT);
+ distance = (distance
+ + previousDistance * ProximityInfoParams::PREV_DISTANCE_WEIGHT)
+ / (1.0f + ProximityInfoParams::PREV_DISTANCE_WEIGHT);
}
}
// TODO: Promote the first point when the extended line from the next input is near
@@ -831,8 +810,9 @@ namespace latinime {
const float prevDistance = sqrtf(getPointToKeyByIdLength(
maxPointToKeyLength, SampledDistanceCache_G, keyCount, i + 1, j));
if (prevDistance < distance) {
- distance = (distance + prevDistance * NEXT_DISTANCE_WEIGHT)
- / (1.0f + NEXT_DISTANCE_WEIGHT);
+ distance = (distance
+ + prevDistance * ProximityInfoParams::NEXT_DISTANCE_WEIGHT)
+ / (1.0f + ProximityInfoParams::NEXT_DISTANCE_WEIGHT);
}
} else if (i != 0 && i == sampledInputSize - 1) {
// For the first point, weighted average of distances from last point and
@@ -840,8 +820,9 @@ namespace latinime {
const float prevDistance = sqrtf(getPointToKeyByIdLength(
maxPointToKeyLength, SampledDistanceCache_G, keyCount, i - 1, j));
if (prevDistance < distance) {
- distance = (distance + prevDistance * PREV_DISTANCE_WEIGHT)
- / (1.0f + PREV_DISTANCE_WEIGHT);
+ distance = (distance
+ + prevDistance * ProximityInfoParams::PREV_DISTANCE_WEIGHT)
+ / (1.0f + ProximityInfoParams::PREV_DISTANCE_WEIGHT);
}
}
const float probabilityDensity = distribution.getProbabilityDensity(distance);
@@ -905,7 +886,7 @@ namespace latinime {
hash_map_compat<int, float>::iterator it = (*charProbabilities)[i].find(j);
if (it == (*charProbabilities)[i].end()){
(*SampledNearKeysVector)[i].reset(j);
- } else if(it->second < MIN_PROBABILITY) {
+ } else if(it->second < ProximityInfoParams::MIN_PROBABILITY) {
// Erases from near keys vector because it has very low probability.
(*SampledNearKeysVector)[i].reset(j);
(*charProbabilities)[i].erase(j);
@@ -949,20 +930,14 @@ namespace latinime {
std::vector<hash_map_compat<int, float> > *charProbabilities) {
ASSERT(0 <= index0 && index0 < sampledInputSize);
ASSERT(0 <= index1 && index1 < sampledInputSize);
-
- static const float SUPPRESSION_LENGTH_WEIGHT = 1.5f;
- static const float MIN_SUPPRESSION_RATE = 0.1f;
- static const float SUPPRESSION_WEIGHT = 0.5f;
- static const float SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN = 0.1f;
- static const float SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN = 0.3f;
-
const float keyWidthFloat = static_cast<float>(mostCommonKeyWidth);
const float diff = fabsf(static_cast<float>((*lengthCache)[index0] - (*lengthCache)[index1]));
- if (diff > keyWidthFloat * SUPPRESSION_LENGTH_WEIGHT) {
+ if (diff > keyWidthFloat * ProximityInfoParams::SUPPRESSION_LENGTH_WEIGHT) {
return false;
}
- const float suppressionRate = MIN_SUPPRESSION_RATE
- + diff / keyWidthFloat / SUPPRESSION_LENGTH_WEIGHT * SUPPRESSION_WEIGHT;
+ const float suppressionRate = ProximityInfoParams::MIN_SUPPRESSION_RATE
+ + diff / keyWidthFloat / ProximityInfoParams::SUPPRESSION_LENGTH_WEIGHT
+ * ProximityInfoParams::SUPPRESSION_WEIGHT;
for (hash_map_compat<int, float>::iterator it = (*charProbabilities)[index0].begin();
it != (*charProbabilities)[index0].end(); ++it) {
hash_map_compat<int, float>::iterator it2 = (*charProbabilities)[index1].find(it->first);
@@ -974,9 +949,10 @@ namespace latinime {
(*charProbabilities)[index0][NOT_AN_INDEX] += suppression;
// Add the probability of the same key nearby index1
- const float probabilityGain = min(suppression * SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN,
+ const float probabilityGain = min(suppression
+ * ProximityInfoParams::SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN,
(*charProbabilities)[index1][NOT_AN_INDEX]
- * SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN);
+ * ProximityInfoParams::SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN);
it2->second += probabilityGain;
(*charProbabilities)[index1][NOT_AN_INDEX] -= probabilityGain;
}
@@ -1020,7 +996,6 @@ namespace latinime {
int *const codePointBuf) {
ASSERT(sampledInputSize >= 0);
memset(codePointBuf, 0, sizeof(codePointBuf[0]) * MAX_WORD_LENGTH);
- static const float DEMOTION_LOG_PROBABILITY = 0.3f;
int index = 0;
float sumLogProbability = 0.0f;
// TODO: Current implementation is greedy algorithm. DP would be efficient for many cases.
@@ -1030,7 +1005,7 @@ namespace latinime {
for (hash_map_compat<int, float>::const_iterator it = (*charProbabilities)[i].begin();
it != (*charProbabilities)[i].end(); ++it) {
const float logProbability = (it->first != NOT_AN_INDEX)
- ? it->second + DEMOTION_LOG_PROBABILITY : it->second;
+ ? it->second + ProximityInfoParams::DEMOTION_LOG_PROBABILITY : it->second;
if (logProbability < minLogProbability) {
minLogProbability = logProbability;
character = it->first;