am de1ec79a
: Merge "Cleanup in ProximityInfoStateUtils"
# Via Android (Google) Code Review (1) and Ken Wakasa (1) * commit 'de1ec79a357505251c5dad91ebd34ffbcbc03c08': Cleanup in ProximityInfoStateUtils
This commit is contained in:
commit
6984e77441
5 changed files with 224 additions and 163 deletions
|
@ -14,6 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "defines.h"
|
||||||
#include "proximity_info_params.h"
|
#include "proximity_info_params.h"
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
@ -26,10 +27,17 @@ const int ProximityInfoParams::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR =
|
||||||
1 << NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
|
1 << NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
|
||||||
const float ProximityInfoParams::NOT_A_DISTANCE_FLOAT = -1.0f;
|
const float ProximityInfoParams::NOT_A_DISTANCE_FLOAT = -1.0f;
|
||||||
|
|
||||||
// Per method constants
|
/* Per method constants */
|
||||||
|
// Used by ProximityInfoStateUtils::initGeometricDistanceInfos()
|
||||||
const float ProximityInfoParams::NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD = 4.0f;
|
const float ProximityInfoParams::NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD = 4.0f;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::updateNearKeysDistances()
|
||||||
const float ProximityInfoParams::NEAR_KEY_THRESHOLD_FOR_DISTANCE = 2.0f;
|
const float ProximityInfoParams::NEAR_KEY_THRESHOLD_FOR_DISTANCE = 2.0f;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::isPrevLocalMin()
|
||||||
const float ProximityInfoParams::MARGIN_FOR_PREV_LOCAL_MIN = 0.01f;
|
const float ProximityInfoParams::MARGIN_FOR_PREV_LOCAL_MIN = 0.01f;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::getPointScore()
|
||||||
const int ProximityInfoParams::DISTANCE_BASE_SCALE = 100;
|
const int ProximityInfoParams::DISTANCE_BASE_SCALE = 100;
|
||||||
const float ProximityInfoParams::NEAR_KEY_THRESHOLD_FOR_POINT_SCORE = 0.6f;
|
const float ProximityInfoParams::NEAR_KEY_THRESHOLD_FOR_POINT_SCORE = 0.6f;
|
||||||
const int ProximityInfoParams::CORNER_CHECK_DISTANCE_THRESHOLD_SCALE = 25;
|
const int ProximityInfoParams::CORNER_CHECK_DISTANCE_THRESHOLD_SCALE = 25;
|
||||||
|
@ -39,6 +47,52 @@ const float ProximityInfoParams::CORNER_ANGLE_THRESHOLD_FOR_POINT_SCORE = M_PI_F
|
||||||
const float ProximityInfoParams::CORNER_SUM_ANGLE_THRESHOLD = M_PI_F / 4.0f;
|
const float ProximityInfoParams::CORNER_SUM_ANGLE_THRESHOLD = M_PI_F / 4.0f;
|
||||||
const float ProximityInfoParams::CORNER_SCORE = 1.0f;
|
const float ProximityInfoParams::CORNER_SCORE = 1.0f;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::refreshSpeedRates()
|
||||||
|
const int ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION = 2;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::pushTouchPoint()
|
||||||
|
const int ProximityInfoParams::LAST_POINT_SKIP_DISTANCE_SCALE = 4;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::updateAlignPointProbabilities()
|
||||||
|
const float ProximityInfoParams::MIN_PROBABILITY = 0.000001f;
|
||||||
|
const float ProximityInfoParams::MAX_SKIP_PROBABILITY = 0.95f;
|
||||||
|
const float ProximityInfoParams::SKIP_FIRST_POINT_PROBABILITY = 0.01f;
|
||||||
|
const float ProximityInfoParams::SKIP_LAST_POINT_PROBABILITY = 0.1f;
|
||||||
|
const float ProximityInfoParams::MIN_SPEED_RATE_FOR_SKIP_PROBABILITY = 0.15f;
|
||||||
|
const float ProximityInfoParams::SPEED_WEIGHT_FOR_SKIP_PROBABILITY = 0.9f;
|
||||||
|
const float ProximityInfoParams::SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY = 0.6f;
|
||||||
|
const float ProximityInfoParams::NEAREST_DISTANCE_WEIGHT = 0.5f;
|
||||||
|
const float ProximityInfoParams::NEAREST_DISTANCE_BIAS = 0.5f;
|
||||||
|
const float ProximityInfoParams::NEAREST_DISTANCE_WEIGHT_FOR_LAST = 0.6f;
|
||||||
|
const float ProximityInfoParams::NEAREST_DISTANCE_BIAS_FOR_LAST = 0.4f;
|
||||||
|
const float ProximityInfoParams::ANGLE_WEIGHT = 0.90f;
|
||||||
|
const float ProximityInfoParams::DEEP_CORNER_ANGLE_THRESHOLD = M_PI_F * 60.0f / 180.0f;
|
||||||
|
const float ProximityInfoParams::SKIP_DEEP_CORNER_PROBABILITY = 0.1f;
|
||||||
|
const float ProximityInfoParams::CORNER_ANGLE_THRESHOLD = M_PI_F * 30.0f / 180.0f;
|
||||||
|
const float ProximityInfoParams::STRAIGHT_ANGLE_THRESHOLD = M_PI_F * 15.0f / 180.0f;
|
||||||
|
const float ProximityInfoParams::SKIP_CORNER_PROBABILITY = 0.4f;
|
||||||
|
const float ProximityInfoParams::SPEED_MARGIN = 0.1f;
|
||||||
|
const float ProximityInfoParams::CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION = 0.0f;
|
||||||
|
// TODO: The variance is critical for accuracy; thus, adjusting these parameter by machine
|
||||||
|
// learning or something would be efficient.
|
||||||
|
const float ProximityInfoParams::SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION = 0.3f;
|
||||||
|
const float ProximityInfoParams::MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION = 0.25f;
|
||||||
|
const float ProximityInfoParams::SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION = 0.5f;
|
||||||
|
const float ProximityInfoParams::MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION = 0.15f;
|
||||||
|
const float ProximityInfoParams::MIN_STANDERD_DIVIATION = 0.37f;
|
||||||
|
const float ProximityInfoParams::PREV_DISTANCE_WEIGHT = 0.5f;
|
||||||
|
const float ProximityInfoParams::NEXT_DISTANCE_WEIGHT = 0.6f;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::suppressCharProbabilities()
|
||||||
|
const float ProximityInfoParams::SUPPRESSION_LENGTH_WEIGHT = 1.5f;
|
||||||
|
const float ProximityInfoParams::MIN_SUPPRESSION_RATE = 0.1f;
|
||||||
|
const float ProximityInfoParams::SUPPRESSION_WEIGHT = 0.5f;
|
||||||
|
const float ProximityInfoParams::SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN = 0.1f;
|
||||||
|
const float ProximityInfoParams::SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN = 0.3f;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::getMostProbableString()
|
||||||
|
const float ProximityInfoParams::DEMOTION_LOG_PROBABILITY = 0.3f;
|
||||||
|
|
||||||
// TODO: Investigate if this is required
|
// TODO: Investigate if this is required
|
||||||
const float ProximityInfoParams::SEARCH_KEY_RADIUS_RATIO = 0.95f;
|
const float ProximityInfoParams::SEARCH_KEY_RADIUS_RATIO = 0.95f;
|
||||||
} // namespace latinime
|
} // namespace latinime
|
||||||
|
|
|
@ -50,6 +50,50 @@ class ProximityInfoParams {
|
||||||
static const float CORNER_SUM_ANGLE_THRESHOLD;
|
static const float CORNER_SUM_ANGLE_THRESHOLD;
|
||||||
static const float CORNER_SCORE;
|
static const float CORNER_SCORE;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::refreshSpeedRates()
|
||||||
|
static const int NUM_POINTS_FOR_SPEED_CALCULATION;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::pushTouchPoint()
|
||||||
|
static const int LAST_POINT_SKIP_DISTANCE_SCALE;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::updateAlignPointProbabilities()
|
||||||
|
static const float MIN_PROBABILITY;
|
||||||
|
static const float MAX_SKIP_PROBABILITY;
|
||||||
|
static const float SKIP_FIRST_POINT_PROBABILITY;
|
||||||
|
static const float SKIP_LAST_POINT_PROBABILITY;
|
||||||
|
static const float MIN_SPEED_RATE_FOR_SKIP_PROBABILITY;
|
||||||
|
static const float SPEED_WEIGHT_FOR_SKIP_PROBABILITY;
|
||||||
|
static const float SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY;
|
||||||
|
static const float NEAREST_DISTANCE_WEIGHT;
|
||||||
|
static const float NEAREST_DISTANCE_BIAS;
|
||||||
|
static const float NEAREST_DISTANCE_WEIGHT_FOR_LAST;
|
||||||
|
static const float NEAREST_DISTANCE_BIAS_FOR_LAST;
|
||||||
|
static const float ANGLE_WEIGHT;
|
||||||
|
static const float DEEP_CORNER_ANGLE_THRESHOLD;
|
||||||
|
static const float SKIP_DEEP_CORNER_PROBABILITY;
|
||||||
|
static const float CORNER_ANGLE_THRESHOLD;
|
||||||
|
static const float STRAIGHT_ANGLE_THRESHOLD;
|
||||||
|
static const float SKIP_CORNER_PROBABILITY;
|
||||||
|
static const float SPEED_MARGIN;
|
||||||
|
static const float CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION;
|
||||||
|
static const float SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION;
|
||||||
|
static const float MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION;
|
||||||
|
static const float SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION;
|
||||||
|
static const float MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION;
|
||||||
|
static const float MIN_STANDERD_DIVIATION;
|
||||||
|
static const float PREV_DISTANCE_WEIGHT;
|
||||||
|
static const float NEXT_DISTANCE_WEIGHT;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::suppressCharProbabilities()
|
||||||
|
static const float SUPPRESSION_LENGTH_WEIGHT;
|
||||||
|
static const float MIN_SUPPRESSION_RATE;
|
||||||
|
static const float SUPPRESSION_WEIGHT;
|
||||||
|
static const float SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN;
|
||||||
|
static const float SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN;
|
||||||
|
|
||||||
|
// Used by ProximityInfoStateUtils::getMostProbableString()
|
||||||
|
static const float DEMOTION_LOG_PROBABILITY;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoParams);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoParams);
|
||||||
static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
|
static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
|
||||||
|
|
|
@ -89,29 +89,28 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xCoordinates && yCoordinates) {
|
if (xCoordinates && yCoordinates) {
|
||||||
mSampledInputSize = ProximityInfoStateUtils::updateTouchPoints(
|
mSampledInputSize = ProximityInfoStateUtils::updateTouchPoints(mProximityInfo,
|
||||||
mProximityInfo->getMostCommonKeyWidth(), mProximityInfo, mMaxPointToKeyLength,
|
mMaxPointToKeyLength, mInputProximities, xCoordinates, yCoordinates, times,
|
||||||
mInputProximities, xCoordinates, yCoordinates, times, pointerIds, inputSize,
|
pointerIds, inputSize, isGeometric, pointerId, pushTouchPointStartIndex,
|
||||||
isGeometric, pointerId, pushTouchPointStartIndex, &mSampledInputXs,
|
&mSampledInputXs, &mSampledInputYs, &mSampledTimes, &mSampledLengthCache,
|
||||||
&mSampledInputYs, &mSampledTimes, &mSampledLengthCache, &mSampledInputIndice);
|
&mSampledInputIndice);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSampledInputSize > 0 && isGeometric) {
|
if (mSampledInputSize > 0 && isGeometric) {
|
||||||
mAverageSpeed = ProximityInfoStateUtils::refreshSpeedRates(
|
mAverageSpeed = ProximityInfoStateUtils::refreshSpeedRates(inputSize, xCoordinates,
|
||||||
inputSize, xCoordinates, yCoordinates, times, lastSavedInputSize,
|
yCoordinates, times, lastSavedInputSize, mSampledInputSize, &mSampledInputXs,
|
||||||
mSampledInputSize, &mSampledInputXs, &mSampledInputYs, &mSampledTimes,
|
&mSampledInputYs, &mSampledTimes, &mSampledLengthCache, &mSampledInputIndice,
|
||||||
&mSampledLengthCache, &mSampledInputIndice, &mSpeedRates, &mDirections);
|
&mSpeedRates, &mDirections);
|
||||||
ProximityInfoStateUtils::refreshBeelineSpeedRates(
|
ProximityInfoStateUtils::refreshBeelineSpeedRates(mProximityInfo->getMostCommonKeyWidth(),
|
||||||
mProximityInfo->getMostCommonKeyWidth(), mAverageSpeed, inputSize,
|
mAverageSpeed, inputSize, xCoordinates, yCoordinates, times, mSampledInputSize,
|
||||||
xCoordinates, yCoordinates, times, mSampledInputSize, &mSampledInputXs,
|
&mSampledInputXs, &mSampledInputYs, &mSampledInputIndice,
|
||||||
&mSampledInputYs, &mSampledInputIndice, &mBeelineSpeedPercentiles);
|
&mBeelineSpeedPercentiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSampledInputSize > 0) {
|
if (mSampledInputSize > 0) {
|
||||||
ProximityInfoStateUtils::initGeometricDistanceInfos(
|
ProximityInfoStateUtils::initGeometricDistanceInfos(mProximityInfo, mSampledInputSize,
|
||||||
mProximityInfo, mProximityInfo->getKeyCount(),
|
lastSavedInputSize, &mSampledInputXs, &mSampledInputYs, &mSampledNearKeysVector,
|
||||||
mSampledInputSize, lastSavedInputSize, &mSampledInputXs, &mSampledInputYs,
|
&mSampledDistanceCache_G);
|
||||||
&mSampledNearKeysVector, &mSampledDistanceCache_G);
|
|
||||||
if (isGeometric) {
|
if (isGeometric) {
|
||||||
// updates probabilities of skipping or mapping each key for all points.
|
// updates probabilities of skipping or mapping each key for all points.
|
||||||
ProximityInfoStateUtils::updateAlignPointProbabilities(
|
ProximityInfoStateUtils::updateAlignPointProbabilities(
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace latinime {
|
||||||
return nextStartIndex;
|
return nextStartIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ int ProximityInfoStateUtils::updateTouchPoints(const int mostCommonKeyWidth,
|
/* static */ int ProximityInfoStateUtils::updateTouchPoints(
|
||||||
const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
|
const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
|
||||||
const int *const inputProximities, const int *const inputXCoordinates,
|
const int *const inputProximities, const int *const inputXCoordinates,
|
||||||
const int *const inputYCoordinates, const int *const times, const int *const pointerIds,
|
const int *const inputYCoordinates, const int *const times, const int *const pointerIds,
|
||||||
|
@ -106,15 +106,14 @@ namespace latinime {
|
||||||
const float prevAngle = getAngle(
|
const float prevAngle = getAngle(
|
||||||
inputXCoordinates[i - 2], inputYCoordinates[i - 2],
|
inputXCoordinates[i - 2], inputYCoordinates[i - 2],
|
||||||
inputXCoordinates[i - 1], inputYCoordinates[i - 1]);
|
inputXCoordinates[i - 1], inputYCoordinates[i - 1]);
|
||||||
const float currentAngle =
|
const float currentAngle = getAngle(
|
||||||
getAngle(inputXCoordinates[i - 1], inputYCoordinates[i - 1], x, y);
|
inputXCoordinates[i - 1], inputYCoordinates[i - 1], x, y);
|
||||||
sumAngle += getAngleDiff(prevAngle, currentAngle);
|
sumAngle += getAngleDiff(prevAngle, currentAngle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pushTouchPoint(mostCommonKeyWidth, proximityInfo, maxPointToKeyLength,
|
if (pushTouchPoint(proximityInfo, maxPointToKeyLength, i, c, x, y, time,
|
||||||
i, c, x, y, time, isGeometric /* doSampling */,
|
isGeometric /* doSampling */, i == lastInputIndex, sumAngle,
|
||||||
i == lastInputIndex, sumAngle, currentNearKeysDistances,
|
currentNearKeysDistances, prevNearKeysDistances, prevPrevNearKeysDistances,
|
||||||
prevNearKeysDistances, prevPrevNearKeysDistances,
|
|
||||||
sampledInputXs, sampledInputYs, sampledInputTimes, sampledLengthCache,
|
sampledInputXs, sampledInputYs, sampledInputTimes, sampledLengthCache,
|
||||||
sampledInputIndice)) {
|
sampledInputIndice)) {
|
||||||
// Previous point information was popped.
|
// Previous point information was popped.
|
||||||
|
@ -222,12 +221,13 @@ namespace latinime {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ProximityInfoStateUtils::initGeometricDistanceInfos(
|
/* 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 int lastSavedInputSize, const std::vector<int> *const sampledInputXs,
|
||||||
const std::vector<int> *const sampledInputYs,
|
const std::vector<int> *const sampledInputYs,
|
||||||
std::vector<NearKeycodesSet> *SampledNearKeysVector,
|
std::vector<NearKeycodesSet> *SampledNearKeysVector,
|
||||||
std::vector<float> *SampledDistanceCache_G) {
|
std::vector<float> *SampledDistanceCache_G) {
|
||||||
SampledNearKeysVector->resize(sampledInputSize);
|
SampledNearKeysVector->resize(sampledInputSize);
|
||||||
|
const int keyCount = proximityInfo->getKeyCount();
|
||||||
SampledDistanceCache_G->resize(sampledInputSize * keyCount);
|
SampledDistanceCache_G->resize(sampledInputSize * keyCount);
|
||||||
for (int i = lastSavedInputSize; i < sampledInputSize; ++i) {
|
for (int i = lastSavedInputSize; i < sampledInputSize; ++i) {
|
||||||
(*SampledNearKeysVector)[i].reset();
|
(*SampledNearKeysVector)[i].reset();
|
||||||
|
@ -275,10 +275,11 @@ namespace latinime {
|
||||||
int duration = 0;
|
int duration = 0;
|
||||||
|
|
||||||
// Calculate velocity by using distances and durations of
|
// Calculate velocity by using distances and durations of
|
||||||
// NUM_POINTS_FOR_SPEED_CALCULATION points for both forward and backward.
|
// ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION points for both forward and
|
||||||
static const int NUM_POINTS_FOR_SPEED_CALCULATION = 2;
|
// backward.
|
||||||
for (int j = index; j < min(inputSize - 1, index + NUM_POINTS_FOR_SPEED_CALCULATION);
|
const int forwardNumPoints = min(inputSize - 1,
|
||||||
++j) {
|
index + ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION);
|
||||||
|
for (int j = index; j < forwardNumPoints; ++j) {
|
||||||
if (i < sampledInputSize - 1 && j >= (*sampledInputIndice)[i + 1]) {
|
if (i < sampledInputSize - 1 && j >= (*sampledInputIndice)[i + 1]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -286,7 +287,9 @@ namespace latinime {
|
||||||
xCoordinates[j + 1], yCoordinates[j + 1]);
|
xCoordinates[j + 1], yCoordinates[j + 1]);
|
||||||
duration += times[j + 1] - times[j];
|
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]) {
|
if (i > 0 && j < (*sampledInputIndice)[i - 1]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -434,9 +437,8 @@ namespace latinime {
|
||||||
|
|
||||||
// Sampling touch point and pushing information to vectors.
|
// Sampling touch point and pushing information to vectors.
|
||||||
// Returning if previous point is popped or not.
|
// Returning if previous point is popped or not.
|
||||||
/* static */ bool ProximityInfoStateUtils::pushTouchPoint(const int mostCommonKeyWidth,
|
/* static */ bool ProximityInfoStateUtils::pushTouchPoint(const ProximityInfo *const proximityInfo,
|
||||||
const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
|
const int maxPointToKeyLength, const int inputIndex, const int nodeCodePoint, int x, int y,
|
||||||
const int inputIndex, const int nodeCodePoint, int x, int y,
|
|
||||||
const int time, const bool doSampling, const bool isLastPoint, const float sumAngle,
|
const int time, const bool doSampling, const bool isLastPoint, const float sumAngle,
|
||||||
NearKeysDistanceMap *const currentNearKeysDistances,
|
NearKeysDistanceMap *const currentNearKeysDistances,
|
||||||
const NearKeysDistanceMap *const prevNearKeysDistances,
|
const NearKeysDistanceMap *const prevNearKeysDistances,
|
||||||
|
@ -444,7 +446,7 @@ namespace latinime {
|
||||||
std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs,
|
std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs,
|
||||||
std::vector<int> *sampledInputTimes, std::vector<int> *sampledLengthCache,
|
std::vector<int> *sampledInputTimes, std::vector<int> *sampledLengthCache,
|
||||||
std::vector<int> *sampledInputIndice) {
|
std::vector<int> *sampledInputIndice) {
|
||||||
static const int LAST_POINT_SKIP_DISTANCE_SCALE = 4;
|
const int mostCommonKeyWidth = proximityInfo->getMostCommonKeyWidth();
|
||||||
|
|
||||||
size_t size = sampledInputXs->size();
|
size_t size = sampledInputXs->size();
|
||||||
bool popped = false;
|
bool popped = false;
|
||||||
|
@ -465,16 +467,16 @@ namespace latinime {
|
||||||
}
|
}
|
||||||
// Check if the last point should be skipped.
|
// Check if the last point should be skipped.
|
||||||
if (isLastPoint && size > 0) {
|
if (isLastPoint && size > 0) {
|
||||||
if (getDistanceInt(x, y, sampledInputXs->back(),
|
if (getDistanceInt(x, y, sampledInputXs->back(), sampledInputYs->back())
|
||||||
sampledInputYs->back()) * LAST_POINT_SKIP_DISTANCE_SCALE
|
* ProximityInfoParams::LAST_POINT_SKIP_DISTANCE_SCALE < mostCommonKeyWidth) {
|
||||||
< mostCommonKeyWidth) {
|
|
||||||
// This point is not used because it's too close to the previous point.
|
// This point is not used because it's too close to the previous point.
|
||||||
if (DEBUG_GEO_FULL) {
|
if (DEBUG_GEO_FULL) {
|
||||||
AKLOGI("p0: size = %zd, x = %d, y = %d, lx = %d, ly = %d, dist = %d, "
|
AKLOGI("p0: size = %zd, x = %d, y = %d, lx = %d, ly = %d, dist = %d, "
|
||||||
"width = %d", size, x, y, sampledInputXs->back(),
|
"width = %d", size, x, y, sampledInputXs->back(),
|
||||||
sampledInputYs->back(), getDistanceInt(
|
sampledInputYs->back(), getDistanceInt(
|
||||||
x, y, sampledInputXs->back(), sampledInputYs->back()),
|
x, y, sampledInputXs->back(), sampledInputYs->back()),
|
||||||
mostCommonKeyWidth / LAST_POINT_SKIP_DISTANCE_SCALE);
|
mostCommonKeyWidth
|
||||||
|
/ ProximityInfoParams::LAST_POINT_SKIP_DISTANCE_SCALE);
|
||||||
}
|
}
|
||||||
return popped;
|
return popped;
|
||||||
}
|
}
|
||||||
|
@ -664,35 +666,14 @@ namespace latinime {
|
||||||
const std::vector<float> *const SampledDistanceCache_G,
|
const std::vector<float> *const SampledDistanceCache_G,
|
||||||
std::vector<NearKeycodesSet> *SampledNearKeysVector,
|
std::vector<NearKeycodesSet> *SampledNearKeysVector,
|
||||||
std::vector<hash_map_compat<int, float> > *charProbabilities) {
|
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);
|
charProbabilities->resize(sampledInputSize);
|
||||||
// Calculates probabilities of using a point as a correlated point with the character
|
// Calculates probabilities of using a point as a correlated point with the character
|
||||||
// for each point.
|
// for each point.
|
||||||
for (int i = start; i < sampledInputSize; ++i) {
|
for (int i = start; i < sampledInputSize; ++i) {
|
||||||
(*charProbabilities)[i].clear();
|
(*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];
|
// 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 currentAngle = getPointAngle(sampledInputXs, sampledInputYs, i);
|
||||||
const float speedRate = (*sampledSpeedRates)[i];
|
const float speedRate = (*sampledSpeedRates)[i];
|
||||||
|
@ -709,78 +690,74 @@ namespace latinime {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
skipProbability *= min(1.0f, nearestKeyDistance * NEAREST_DISTANCE_WEIGHT
|
skipProbability *= min(1.0f,
|
||||||
+ NEAREST_DISTANCE_BIAS);
|
nearestKeyDistance * ProximityInfoParams::NEAREST_DISTANCE_WEIGHT
|
||||||
|
+ ProximityInfoParams::NEAREST_DISTANCE_BIAS);
|
||||||
// Promote the first point
|
// Promote the first point
|
||||||
skipProbability *= SKIP_FIRST_POINT_PROBABILITY;
|
skipProbability *= ProximityInfoParams::SKIP_FIRST_POINT_PROBABILITY;
|
||||||
} else if (i == sampledInputSize - 1) {
|
} else if (i == sampledInputSize - 1) {
|
||||||
skipProbability *= min(1.0f, nearestKeyDistance * NEAREST_DISTANCE_WEIGHT_FOR_LAST
|
skipProbability *= min(1.0f,
|
||||||
+ NEAREST_DISTANCE_BIAS_FOR_LAST);
|
nearestKeyDistance * ProximityInfoParams::NEAREST_DISTANCE_WEIGHT_FOR_LAST
|
||||||
|
+ ProximityInfoParams::NEAREST_DISTANCE_BIAS_FOR_LAST);
|
||||||
// Promote the last point
|
// Promote the last point
|
||||||
skipProbability *= SKIP_LAST_POINT_PROBABILITY;
|
skipProbability *= ProximityInfoParams::SKIP_LAST_POINT_PROBABILITY;
|
||||||
} else {
|
} else {
|
||||||
// If the current speed is relatively slower than adjacent keys, we promote this point.
|
// If the current speed is relatively slower than adjacent keys, we promote this point.
|
||||||
if ((*sampledSpeedRates)[i - 1] - SPEED_MARGIN > speedRate
|
if ((*sampledSpeedRates)[i - 1] - ProximityInfoParams::SPEED_MARGIN > speedRate
|
||||||
&& speedRate < (*sampledSpeedRates)[i + 1] - SPEED_MARGIN) {
|
&& speedRate
|
||||||
if (currentAngle < CORNER_ANGLE_THRESHOLD) {
|
< (*sampledSpeedRates)[i + 1] - ProximityInfoParams::SPEED_MARGIN) {
|
||||||
|
if (currentAngle < ProximityInfoParams::CORNER_ANGLE_THRESHOLD) {
|
||||||
skipProbability *= min(1.0f, speedRate
|
skipProbability *= min(1.0f, speedRate
|
||||||
* SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY);
|
* ProximityInfoParams::SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY);
|
||||||
} else {
|
} else {
|
||||||
// If the angle is small enough, we promote this point more. (e.g. pit vs put)
|
// 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
|
skipProbability *= min(1.0f,
|
||||||
+ MIN_SPEED_RATE_FOR_SKIP_PROBABILITY);
|
speedRate * ProximityInfoParams::SPEED_WEIGHT_FOR_SKIP_PROBABILITY
|
||||||
|
+ ProximityInfoParams::MIN_SPEED_RATE_FOR_SKIP_PROBABILITY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skipProbability *= min(1.0f, speedRate * nearestKeyDistance *
|
skipProbability *= min(1.0f,
|
||||||
NEAREST_DISTANCE_WEIGHT + NEAREST_DISTANCE_BIAS);
|
speedRate * nearestKeyDistance * ProximityInfoParams::NEAREST_DISTANCE_WEIGHT
|
||||||
|
+ ProximityInfoParams::NEAREST_DISTANCE_BIAS);
|
||||||
|
|
||||||
// Adjusts skip probability by a rate depending on angle.
|
// Adjusts skip probability by a rate depending on angle.
|
||||||
// ANGLE_RATE of skipProbability is adjusted by current angle.
|
// ANGLE_RATE of skipProbability is adjusted by current angle.
|
||||||
skipProbability *= (M_PI_F - currentAngle) / M_PI_F * ANGLE_WEIGHT
|
skipProbability *= (M_PI_F - currentAngle) / M_PI_F * ProximityInfoParams::ANGLE_WEIGHT
|
||||||
+ (1.0f - ANGLE_WEIGHT);
|
+ (1.0f - ProximityInfoParams::ANGLE_WEIGHT);
|
||||||
if (currentAngle > DEEP_CORNER_ANGLE_THRESHOLD) {
|
if (currentAngle > ProximityInfoParams::DEEP_CORNER_ANGLE_THRESHOLD) {
|
||||||
skipProbability *= SKIP_DEEP_CORNER_PROBABILITY;
|
skipProbability *= ProximityInfoParams::SKIP_DEEP_CORNER_PROBABILITY;
|
||||||
}
|
}
|
||||||
// We assume the angle of this point is the angle for point[i], point[i - 2]
|
// 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 - 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.
|
// 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);
|
const float prevAngle = getPointsAngle(sampledInputXs, sampledInputYs, i, i - 2, i - 3);
|
||||||
if (i >= 3 && prevAngle < STRAIGHT_ANGLE_THRESHOLD
|
if (i >= 3 && prevAngle < ProximityInfoParams::STRAIGHT_ANGLE_THRESHOLD
|
||||||
&& currentAngle > CORNER_ANGLE_THRESHOLD) {
|
&& currentAngle > ProximityInfoParams::CORNER_ANGLE_THRESHOLD) {
|
||||||
skipProbability *= SKIP_CORNER_PROBABILITY;
|
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 >= 0.0f);
|
||||||
ASSERT(skipProbability <= MAX_SKIP_PROBABILITY);
|
ASSERT(skipProbability <= ProximityInfoParams::MAX_SKIP_PROBABILITY);
|
||||||
(*charProbabilities)[i][NOT_AN_INDEX] = skipProbability;
|
(*charProbabilities)[i][NOT_AN_INDEX] = skipProbability;
|
||||||
|
|
||||||
// Second, calculates key probabilities by dividing the rest probability
|
// Second, calculates key probabilities by dividing the rest probability
|
||||||
// (1.0f - skipProbability).
|
// (1.0f - skipProbability).
|
||||||
const float inputCharProbability = 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
|
const float speedxAngleRate = min(speedRate * currentAngle / M_PI_F
|
||||||
* SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION,
|
* ProximityInfoParams::SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION,
|
||||||
MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION);
|
ProximityInfoParams::MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION);
|
||||||
const float speedxNearestKeyDistanceRate = min(speedRate * nearestKeyDistance
|
const float speedxNearestKeyDistanceRate = min(speedRate * nearestKeyDistance
|
||||||
* SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION,
|
* ProximityInfoParams::SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION,
|
||||||
MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION);
|
ProximityInfoParams::MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION);
|
||||||
const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate + MIN_STANDERD_DIVIATION;
|
const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate
|
||||||
|
+ ProximityInfoParams::MIN_STANDERD_DIVIATION;
|
||||||
|
|
||||||
ProximityInfoUtils::NormalDistribution
|
ProximityInfoUtils::NormalDistribution
|
||||||
distribution(CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
|
distribution(ProximityInfoParams::CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
|
||||||
static const float PREV_DISTANCE_WEIGHT = 0.5f;
|
|
||||||
static const float NEXT_DISTANCE_WEIGHT = 0.6f;
|
|
||||||
// Summing up probability densities of all near keys.
|
// Summing up probability densities of all near keys.
|
||||||
float sumOfProbabilityDensities = 0.0f;
|
float sumOfProbabilityDensities = 0.0f;
|
||||||
for (int j = 0; j < keyCount; ++j) {
|
for (int j = 0; j < keyCount; ++j) {
|
||||||
|
@ -797,8 +774,9 @@ namespace latinime {
|
||||||
// points because the first touch by the user can be sloppy.
|
// 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
|
// So we promote the first point if the distance of that point is larger
|
||||||
// than the distance of the next point.
|
// than the distance of the next point.
|
||||||
distance = (distance + nextDistance * NEXT_DISTANCE_WEIGHT)
|
distance = (distance
|
||||||
/ (1.0f + NEXT_DISTANCE_WEIGHT);
|
+ nextDistance * ProximityInfoParams::NEXT_DISTANCE_WEIGHT)
|
||||||
|
/ (1.0f + ProximityInfoParams::NEXT_DISTANCE_WEIGHT);
|
||||||
}
|
}
|
||||||
} else if (i != 0 && i == sampledInputSize - 1) {
|
} else if (i != 0 && i == sampledInputSize - 1) {
|
||||||
// For the first point, weighted average of distances from last point and
|
// 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
|
// 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
|
// last point if the distance of that point is larger than the distance of
|
||||||
// the previous point.
|
// the previous point.
|
||||||
distance = (distance + previousDistance * PREV_DISTANCE_WEIGHT)
|
distance = (distance
|
||||||
/ (1.0f + PREV_DISTANCE_WEIGHT);
|
+ 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
|
// 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(
|
const float prevDistance = sqrtf(getPointToKeyByIdLength(
|
||||||
maxPointToKeyLength, SampledDistanceCache_G, keyCount, i + 1, j));
|
maxPointToKeyLength, SampledDistanceCache_G, keyCount, i + 1, j));
|
||||||
if (prevDistance < distance) {
|
if (prevDistance < distance) {
|
||||||
distance = (distance + prevDistance * NEXT_DISTANCE_WEIGHT)
|
distance = (distance
|
||||||
/ (1.0f + NEXT_DISTANCE_WEIGHT);
|
+ prevDistance * ProximityInfoParams::NEXT_DISTANCE_WEIGHT)
|
||||||
|
/ (1.0f + ProximityInfoParams::NEXT_DISTANCE_WEIGHT);
|
||||||
}
|
}
|
||||||
} else if (i != 0 && i == sampledInputSize - 1) {
|
} else if (i != 0 && i == sampledInputSize - 1) {
|
||||||
// For the first point, weighted average of distances from last point and
|
// For the first point, weighted average of distances from last point and
|
||||||
|
@ -840,8 +820,9 @@ namespace latinime {
|
||||||
const float prevDistance = sqrtf(getPointToKeyByIdLength(
|
const float prevDistance = sqrtf(getPointToKeyByIdLength(
|
||||||
maxPointToKeyLength, SampledDistanceCache_G, keyCount, i - 1, j));
|
maxPointToKeyLength, SampledDistanceCache_G, keyCount, i - 1, j));
|
||||||
if (prevDistance < distance) {
|
if (prevDistance < distance) {
|
||||||
distance = (distance + prevDistance * PREV_DISTANCE_WEIGHT)
|
distance = (distance
|
||||||
/ (1.0f + PREV_DISTANCE_WEIGHT);
|
+ prevDistance * ProximityInfoParams::PREV_DISTANCE_WEIGHT)
|
||||||
|
/ (1.0f + ProximityInfoParams::PREV_DISTANCE_WEIGHT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const float probabilityDensity = distribution.getProbabilityDensity(distance);
|
const float probabilityDensity = distribution.getProbabilityDensity(distance);
|
||||||
|
@ -905,7 +886,7 @@ namespace latinime {
|
||||||
hash_map_compat<int, float>::iterator it = (*charProbabilities)[i].find(j);
|
hash_map_compat<int, float>::iterator it = (*charProbabilities)[i].find(j);
|
||||||
if (it == (*charProbabilities)[i].end()){
|
if (it == (*charProbabilities)[i].end()){
|
||||||
(*SampledNearKeysVector)[i].reset(j);
|
(*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.
|
// Erases from near keys vector because it has very low probability.
|
||||||
(*SampledNearKeysVector)[i].reset(j);
|
(*SampledNearKeysVector)[i].reset(j);
|
||||||
(*charProbabilities)[i].erase(j);
|
(*charProbabilities)[i].erase(j);
|
||||||
|
@ -949,20 +930,14 @@ namespace latinime {
|
||||||
std::vector<hash_map_compat<int, float> > *charProbabilities) {
|
std::vector<hash_map_compat<int, float> > *charProbabilities) {
|
||||||
ASSERT(0 <= index0 && index0 < sampledInputSize);
|
ASSERT(0 <= index0 && index0 < sampledInputSize);
|
||||||
ASSERT(0 <= index1 && index1 < 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 keyWidthFloat = static_cast<float>(mostCommonKeyWidth);
|
||||||
const float diff = fabsf(static_cast<float>((*lengthCache)[index0] - (*lengthCache)[index1]));
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
const float suppressionRate = MIN_SUPPRESSION_RATE
|
const float suppressionRate = ProximityInfoParams::MIN_SUPPRESSION_RATE
|
||||||
+ diff / keyWidthFloat / SUPPRESSION_LENGTH_WEIGHT * SUPPRESSION_WEIGHT;
|
+ diff / keyWidthFloat / ProximityInfoParams::SUPPRESSION_LENGTH_WEIGHT
|
||||||
|
* ProximityInfoParams::SUPPRESSION_WEIGHT;
|
||||||
for (hash_map_compat<int, float>::iterator it = (*charProbabilities)[index0].begin();
|
for (hash_map_compat<int, float>::iterator it = (*charProbabilities)[index0].begin();
|
||||||
it != (*charProbabilities)[index0].end(); ++it) {
|
it != (*charProbabilities)[index0].end(); ++it) {
|
||||||
hash_map_compat<int, float>::iterator it2 = (*charProbabilities)[index1].find(it->first);
|
hash_map_compat<int, float>::iterator it2 = (*charProbabilities)[index1].find(it->first);
|
||||||
|
@ -974,9 +949,10 @@ namespace latinime {
|
||||||
(*charProbabilities)[index0][NOT_AN_INDEX] += suppression;
|
(*charProbabilities)[index0][NOT_AN_INDEX] += suppression;
|
||||||
|
|
||||||
// Add the probability of the same key nearby index1
|
// 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]
|
(*charProbabilities)[index1][NOT_AN_INDEX]
|
||||||
* SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN);
|
* ProximityInfoParams::SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN);
|
||||||
it2->second += probabilityGain;
|
it2->second += probabilityGain;
|
||||||
(*charProbabilities)[index1][NOT_AN_INDEX] -= probabilityGain;
|
(*charProbabilities)[index1][NOT_AN_INDEX] -= probabilityGain;
|
||||||
}
|
}
|
||||||
|
@ -1020,7 +996,6 @@ namespace latinime {
|
||||||
int *const codePointBuf) {
|
int *const codePointBuf) {
|
||||||
ASSERT(sampledInputSize >= 0);
|
ASSERT(sampledInputSize >= 0);
|
||||||
memset(codePointBuf, 0, sizeof(codePointBuf[0]) * MAX_WORD_LENGTH);
|
memset(codePointBuf, 0, sizeof(codePointBuf[0]) * MAX_WORD_LENGTH);
|
||||||
static const float DEMOTION_LOG_PROBABILITY = 0.3f;
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
float sumLogProbability = 0.0f;
|
float sumLogProbability = 0.0f;
|
||||||
// TODO: Current implementation is greedy algorithm. DP would be efficient for many cases.
|
// 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();
|
for (hash_map_compat<int, float>::const_iterator it = (*charProbabilities)[i].begin();
|
||||||
it != (*charProbabilities)[i].end(); ++it) {
|
it != (*charProbabilities)[i].end(); ++it) {
|
||||||
const float logProbability = (it->first != NOT_AN_INDEX)
|
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) {
|
if (logProbability < minLogProbability) {
|
||||||
minLogProbability = logProbability;
|
minLogProbability = logProbability;
|
||||||
character = it->first;
|
character = it->first;
|
||||||
|
|
|
@ -35,9 +35,8 @@ class ProximityInfoStateUtils {
|
||||||
static int trimLastTwoTouchPoints(std::vector<int> *sampledInputXs,
|
static int trimLastTwoTouchPoints(std::vector<int> *sampledInputXs,
|
||||||
std::vector<int> *sampledInputYs, std::vector<int> *sampledInputTimes,
|
std::vector<int> *sampledInputYs, std::vector<int> *sampledInputTimes,
|
||||||
std::vector<int> *sampledLengthCache, std::vector<int> *sampledInputIndice);
|
std::vector<int> *sampledLengthCache, std::vector<int> *sampledInputIndice);
|
||||||
static int updateTouchPoints(const int mostCommonKeyWidth,
|
static int updateTouchPoints(const ProximityInfo *const proximityInfo,
|
||||||
const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
|
const int maxPointToKeyLength, const int *const inputProximities,
|
||||||
const int *const inputProximities,
|
|
||||||
const int *const inputXCoordinates, const int *const inputYCoordinates,
|
const int *const inputXCoordinates, const int *const inputYCoordinates,
|
||||||
const int *const times, const int *const pointerIds, const int inputSize,
|
const int *const times, const int *const pointerIds, const int inputSize,
|
||||||
const bool isGeometric, const int pointerId, const int pushTouchPointStartIndex,
|
const bool isGeometric, const int pointerId, const int pushTouchPointStartIndex,
|
||||||
|
@ -65,19 +64,17 @@ class ProximityInfoStateUtils {
|
||||||
std::vector<int> *beelineSpeedPercentiles);
|
std::vector<int> *beelineSpeedPercentiles);
|
||||||
static float getDirection(const std::vector<int> *const sampledInputXs,
|
static float getDirection(const std::vector<int> *const sampledInputXs,
|
||||||
const std::vector<int> *const sampledInputYs, const int index0, const int index1);
|
const std::vector<int> *const sampledInputYs, const int index0, const int index1);
|
||||||
static void updateAlignPointProbabilities(
|
static void updateAlignPointProbabilities(const float maxPointToKeyLength,
|
||||||
const float maxPointToKeyLength, const int mostCommonKeyWidth, const int keyCount,
|
const int mostCommonKeyWidth, const int keyCount, const int start,
|
||||||
const int start, const int sampledInputSize,
|
const int sampledInputSize, const std::vector<int> *const sampledInputXs,
|
||||||
const std::vector<int> *const sampledInputXs,
|
|
||||||
const std::vector<int> *const sampledInputYs,
|
const std::vector<int> *const sampledInputYs,
|
||||||
const std::vector<float> *const sampledSpeedRates,
|
const std::vector<float> *const sampledSpeedRates,
|
||||||
const std::vector<int> *const sampledLengthCache,
|
const std::vector<int> *const sampledLengthCache,
|
||||||
const std::vector<float> *const SampledDistanceCache_G,
|
const std::vector<float> *const SampledDistanceCache_G,
|
||||||
std::vector<NearKeycodesSet> *SampledNearKeysVector,
|
std::vector<NearKeycodesSet> *SampledNearKeysVector,
|
||||||
std::vector<hash_map_compat<int, float> > *charProbabilities);
|
std::vector<hash_map_compat<int, float> > *charProbabilities);
|
||||||
static void updateSampledSearchKeysVector(
|
static void updateSampledSearchKeysVector(const ProximityInfo *const proximityInfo,
|
||||||
const ProximityInfo *const proximityInfo, const int sampledInputSize,
|
const int sampledInputSize, const int lastSavedInputSize,
|
||||||
const int lastSavedInputSize,
|
|
||||||
const std::vector<int> *const sampledLengthCache,
|
const std::vector<int> *const sampledLengthCache,
|
||||||
const std::vector<NearKeycodesSet> *const SampledNearKeysVector,
|
const std::vector<NearKeycodesSet> *const SampledNearKeysVector,
|
||||||
std::vector<NearKeycodesSet> *sampledSearchKeysVector);
|
std::vector<NearKeycodesSet> *sampledSearchKeysVector);
|
||||||
|
@ -87,22 +84,18 @@ class ProximityInfoStateUtils {
|
||||||
static float getPointToKeyByIdLength(const float maxPointToKeyLength,
|
static float getPointToKeyByIdLength(const float maxPointToKeyLength,
|
||||||
const std::vector<float> *const SampledDistanceCache_G, const int keyCount,
|
const std::vector<float> *const SampledDistanceCache_G, const int keyCount,
|
||||||
const int inputIndex, const int keyId);
|
const int inputIndex, const int keyId);
|
||||||
static void initGeometricDistanceInfos(
|
static void initGeometricDistanceInfos(const ProximityInfo *const proximityInfo,
|
||||||
const ProximityInfo *const proximityInfo, const int keyCount,
|
|
||||||
const int sampledInputSize, const int lastSavedInputSize,
|
const int sampledInputSize, const int lastSavedInputSize,
|
||||||
const std::vector<int> *const sampledInputXs,
|
const std::vector<int> *const sampledInputXs,
|
||||||
const std::vector<int> *const sampledInputYs,
|
const std::vector<int> *const sampledInputYs,
|
||||||
std::vector<NearKeycodesSet> *SampledNearKeysVector,
|
std::vector<NearKeycodesSet> *SampledNearKeysVector,
|
||||||
std::vector<float> *SampledDistanceCache_G);
|
std::vector<float> *SampledDistanceCache_G);
|
||||||
static void initPrimaryInputWord(
|
static void initPrimaryInputWord(const int inputSize, const int *const inputProximities,
|
||||||
const int inputSize, const int *const inputProximities, int *primaryInputWord);
|
int *primaryInputWord);
|
||||||
static void initNormalizedSquaredDistances(
|
static void initNormalizedSquaredDistances(const ProximityInfo *const proximityInfo,
|
||||||
const ProximityInfo *const proximityInfo, const int inputSize,
|
const int inputSize, const int *inputXCoordinates, const int *inputYCoordinates,
|
||||||
const int *inputXCoordinates, const int *inputYCoordinates,
|
const int *const inputProximities, const std::vector<int> *const sampledInputXs,
|
||||||
const int *const inputProximities,
|
const std::vector<int> *const sampledInputYs, int *normalizedSquaredDistances);
|
||||||
const std::vector<int> *const sampledInputXs,
|
|
||||||
const std::vector<int> *const sampledInputYs,
|
|
||||||
int *normalizedSquaredDistances);
|
|
||||||
static void dump(const bool isGeometric, const int inputSize,
|
static void dump(const bool isGeometric, const int inputSize,
|
||||||
const int *const inputXCoordinates, const int *const inputYCoordinates,
|
const int *const inputXCoordinates, const int *const inputYCoordinates,
|
||||||
const int sampledInputSize, const std::vector<int> *const sampledInputXs,
|
const int sampledInputSize, const std::vector<int> *const sampledInputXs,
|
||||||
|
@ -117,8 +110,8 @@ class ProximityInfoStateUtils {
|
||||||
const std::vector<int> *const sampledTimes,
|
const std::vector<int> *const sampledTimes,
|
||||||
const std::vector<int> *const sampledInputIndices);
|
const std::vector<int> *const sampledInputIndices);
|
||||||
// TODO: Move to most_probable_string_utils.h
|
// TODO: Move to most_probable_string_utils.h
|
||||||
static float getMostProbableString(
|
static float getMostProbableString(const ProximityInfo *const proximityInfo,
|
||||||
const ProximityInfo *const proximityInfo, const int sampledInputSize,
|
const int sampledInputSize,
|
||||||
const std::vector<hash_map_compat<int, float> > *const charProbabilities,
|
const std::vector<hash_map_compat<int, float> > *const charProbabilities,
|
||||||
int *const codePointBuf);
|
int *const codePointBuf);
|
||||||
|
|
||||||
|
@ -137,11 +130,10 @@ class ProximityInfoStateUtils {
|
||||||
const NearKeysDistanceMap *const prevNearKeysDistances,
|
const NearKeysDistanceMap *const prevNearKeysDistances,
|
||||||
const NearKeysDistanceMap *const prevPrevNearKeysDistances,
|
const NearKeysDistanceMap *const prevPrevNearKeysDistances,
|
||||||
std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs);
|
std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs);
|
||||||
static bool pushTouchPoint(const int mostCommonKeyWidth,
|
static bool pushTouchPoint(const ProximityInfo *const proximityInfo,
|
||||||
const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
|
const int maxPointToKeyLength, const int inputIndex, const int nodeCodePoint, int x,
|
||||||
const int inputIndex, const int nodeCodePoint, int x, int y, const int time,
|
int y, const int time, const bool doSampling, const bool isLastPoint,
|
||||||
const bool doSampling, const bool isLastPoint, const float sumAngle,
|
const float sumAngle, NearKeysDistanceMap *const currentNearKeysDistances,
|
||||||
NearKeysDistanceMap *const currentNearKeysDistances,
|
|
||||||
const NearKeysDistanceMap *const prevNearKeysDistances,
|
const NearKeysDistanceMap *const prevNearKeysDistances,
|
||||||
const NearKeysDistanceMap *const prevPrevNearKeysDistances,
|
const NearKeysDistanceMap *const prevPrevNearKeysDistances,
|
||||||
std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs,
|
std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs,
|
||||||
|
@ -153,23 +145,20 @@ class ProximityInfoStateUtils {
|
||||||
const std::vector<int> *const sampledInputXs,
|
const std::vector<int> *const sampledInputXs,
|
||||||
const std::vector<int> *const sampledInputYs,
|
const std::vector<int> *const sampledInputYs,
|
||||||
const std::vector<int> *const inputIndice);
|
const std::vector<int> *const inputIndice);
|
||||||
static float getPointAngle(
|
static float getPointAngle(const std::vector<int> *const sampledInputXs,
|
||||||
const std::vector<int> *const sampledInputXs,
|
|
||||||
const std::vector<int> *const sampledInputYs, const int index);
|
const std::vector<int> *const sampledInputYs, const int index);
|
||||||
static float getPointsAngle(
|
static float getPointsAngle(const std::vector<int> *const sampledInputXs,
|
||||||
const std::vector<int> *const sampledInputXs,
|
const std::vector<int> *const sampledInputYs, const int index0, const int index1,
|
||||||
const std::vector<int> *const sampledInputYs,
|
const int index2);
|
||||||
const int index0, const int index1, const int index2);
|
|
||||||
static bool suppressCharProbabilities(const int mostCommonKeyWidth,
|
static bool suppressCharProbabilities(const int mostCommonKeyWidth,
|
||||||
const int sampledInputSize, const std::vector<int> *const lengthCache,
|
const int sampledInputSize, const std::vector<int> *const lengthCache, const int index0,
|
||||||
const int index0, const int index1,
|
const int index1, std::vector<hash_map_compat<int, float> > *charProbabilities);
|
||||||
std::vector<hash_map_compat<int, float> > *charProbabilities);
|
|
||||||
static float calculateSquaredDistanceFromSweetSpotCenter(
|
static float calculateSquaredDistanceFromSweetSpotCenter(
|
||||||
const ProximityInfo *const proximityInfo, const std::vector<int> *const sampledInputXs,
|
const ProximityInfo *const proximityInfo, const std::vector<int> *const sampledInputXs,
|
||||||
const std::vector<int> *const sampledInputYs, const int keyIndex,
|
const std::vector<int> *const sampledInputYs, const int keyIndex,
|
||||||
const int inputIndex);
|
const int inputIndex);
|
||||||
static float calculateNormalizedSquaredDistance(
|
static float calculateNormalizedSquaredDistance(const ProximityInfo *const proximityInfo,
|
||||||
const ProximityInfo *const proximityInfo, const std::vector<int> *const sampledInputXs,
|
const std::vector<int> *const sampledInputXs,
|
||||||
const std::vector<int> *const sampledInputYs, const int keyIndex, const int inputIndex);
|
const std::vector<int> *const sampledInputYs, const int keyIndex, const int inputIndex);
|
||||||
};
|
};
|
||||||
} // namespace latinime
|
} // namespace latinime
|
||||||
|
|
Loading…
Reference in a new issue