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:
Ken Wakasa 2013-01-31 23:24:54 -08:00 committed by Android Git Automerger
commit 6984e77441
5 changed files with 224 additions and 163 deletions

View file

@ -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

View file

@ -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;

View file

@ -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(

View file

@ -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;

View file

@ -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