am 7c7d7115: Merge "refactor proximity info state"

* commit '7c7d7115b7cd27c4ff4892b519cce7872031bf79':
  refactor proximity info state
main
Satoshi Kataoka 2013-01-22 00:58:15 -08:00 committed by Android Git Automerger
commit 79f098abba
7 changed files with 234 additions and 152 deletions

View File

@ -21,4 +21,8 @@ const int ProximityInfoParams::LOOKUP_RADIUS_PERCENTILE = 50;
const int ProximityInfoParams::FIRST_POINT_TIME_OFFSET_MILLIS = 150;
const int ProximityInfoParams::STRONG_DOUBLE_LETTER_TIME_MILLIS = 600;
const int ProximityInfoParams::MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE = 5;
const int ProximityInfoParams::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2 = 10;
const int ProximityInfoParams::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR =
1 << NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
const float ProximityInfoParams::NOT_A_DISTANCE_FLOAT = -1.0f;
} // namespace latinime

View File

@ -27,8 +27,11 @@ class ProximityInfoParams {
static const int FIRST_POINT_TIME_OFFSET_MILLIS;
static const int STRONG_DOUBLE_LETTER_TIME_MILLIS;
static const int MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE;
static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR;
static const float NOT_A_DISTANCE_FLOAT;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoParams);
static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
};
} // namespace latinime
#endif // LATINIME_PROXIMITY_INFO_PARAMS_H

View File

@ -27,10 +27,6 @@
namespace latinime {
const int ProximityInfoState::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2 = 10;
const int ProximityInfoState::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR =
1 << NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
const float ProximityInfoState::NOT_A_DISTANCE_FLOAT = -1.0f;
const int ProximityInfoState::NOT_A_CODE = -1;
void ProximityInfoState::initInputParams(const int pointerId, const float maxPointToKeyLength,
@ -61,10 +57,10 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
int pushTouchPointStartIndex = 0;
int lastSavedInputSize = 0;
mMaxPointToKeyLength = maxPointToKeyLength;
if (mIsContinuationPossible && mInputIndice.size() > 1) {
if (mIsContinuationPossible && mSampledInputIndice.size() > 1) {
// Just update difference.
// Two points prior is never skipped. Thus, we pop 2 input point data here.
pushTouchPointStartIndex = mInputIndice[mInputIndice.size() - 2];
pushTouchPointStartIndex = mSampledInputIndice[mSampledInputIndice.size() - 2];
popInputData();
popInputData();
lastSavedInputSize = mSampledInputXs.size();
@ -72,9 +68,9 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
// Clear all data.
mSampledInputXs.clear();
mSampledInputYs.clear();
mTimes.clear();
mInputIndice.clear();
mLengthCache.clear();
mSampledTimes.clear();
mSampledInputIndice.clear();
mSampledLengthCache.clear();
mDistanceCache_G.clear();
mNearKeysVector.clear();
mSearchKeysVector.clear();
@ -93,56 +89,33 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
mSampledInputSize = ProximityInfoStateUtils::updateTouchPoints(
mProximityInfo->getMostCommonKeyWidth(), mProximityInfo, mMaxPointToKeyLength,
mInputProximities, xCoordinates, yCoordinates, times, pointerIds, inputSize,
isGeometric, pointerId, pushTouchPointStartIndex,
&mSampledInputXs, &mSampledInputYs, &mTimes, &mLengthCache, &mInputIndice);
isGeometric, pointerId, pushTouchPointStartIndex, &mSampledInputXs,
&mSampledInputYs, &mSampledTimes, &mSampledLengthCache, &mSampledInputIndice);
}
if (mSampledInputSize > 0 && isGeometric) {
mAverageSpeed = ProximityInfoStateUtils::refreshSpeedRates(
inputSize, xCoordinates, yCoordinates, times, lastSavedInputSize,
mSampledInputSize, &mSampledInputXs, &mSampledInputYs, &mTimes, &mLengthCache,
&mInputIndice, &mSpeedRates, &mDirections);
mSampledInputSize, &mSampledInputXs, &mSampledInputYs, &mSampledTimes,
&mSampledLengthCache, &mSampledInputIndice, &mSpeedRates, &mDirections);
ProximityInfoStateUtils::refreshBeelineSpeedRates(
mProximityInfo->getMostCommonKeyWidth(), mAverageSpeed, inputSize,
xCoordinates, yCoordinates, times, mSampledInputSize, &mSampledInputXs,
&mSampledInputYs, &mInputIndice, &mBeelineSpeedPercentiles);
}
if (DEBUG_GEO_FULL) {
for (int i = 0; i < mSampledInputSize; ++i) {
AKLOGI("Sampled(%d): x = %d, y = %d, time = %d", i, mSampledInputXs[i],
mSampledInputYs[i], mTimes[i]);
}
&mSampledInputYs, &mSampledInputIndice, &mBeelineSpeedPercentiles);
}
if (mSampledInputSize > 0) {
const int keyCount = mProximityInfo->getKeyCount();
mNearKeysVector.resize(mSampledInputSize);
mSearchKeysVector.resize(mSampledInputSize);
mDistanceCache_G.resize(mSampledInputSize * keyCount);
for (int i = lastSavedInputSize; i < mSampledInputSize; ++i) {
mNearKeysVector[i].reset();
mSearchKeysVector[i].reset();
static const float NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD = 4.0f;
for (int k = 0; k < keyCount; ++k) {
const int index = i * keyCount + k;
const int x = mSampledInputXs[i];
const int y = mSampledInputYs[i];
const float normalizedSquaredDistance =
mProximityInfo->getNormalizedSquaredDistanceFromCenterFloatG(k, x, y);
mDistanceCache_G[index] = normalizedSquaredDistance;
if (normalizedSquaredDistance < NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD) {
mNearKeysVector[i][k] = true;
}
}
}
ProximityInfoStateUtils::initGeometricDistanceInfos(
mProximityInfo, mProximityInfo->getKeyCount(),
mSampledInputSize, lastSavedInputSize, &mSampledInputXs, &mSampledInputYs,
&mNearKeysVector, &mSearchKeysVector, &mDistanceCache_G);
if (isGeometric) {
// updates probabilities of skipping or mapping each key for all points.
ProximityInfoStateUtils::updateAlignPointProbabilities(
mMaxPointToKeyLength, mProximityInfo->getMostCommonKeyWidth(),
keyCount, lastSavedInputSize, mSampledInputSize, &mSampledInputXs,
&mSampledInputYs, &mSpeedRates, &mLengthCache, &mDistanceCache_G,
&mNearKeysVector, &mCharProbabilities);
mProximityInfo->getKeyCount(), lastSavedInputSize, mSampledInputSize,
&mSampledInputXs, &mSampledInputYs, &mSpeedRates, &mSampledLengthCache,
&mDistanceCache_G, &mNearKeysVector, &mCharProbabilities);
static const float READ_FORWORD_LENGTH_SCALE = 0.95f;
const int readForwordLength = static_cast<int>(
@ -153,7 +126,7 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
mSearchKeysVector[i].reset();
}
for (int j = max(i, lastSavedInputSize); j < mSampledInputSize; ++j) {
if (mLengthCache[j] - mLengthCache[i] >= readForwordLength) {
if (mSampledLengthCache[j] - mSampledLengthCache[i] >= readForwordLength) {
break;
}
mSearchKeysVector[i] |= mNearKeysVector[j];
@ -163,32 +136,9 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
}
if (DEBUG_SAMPLING_POINTS) {
std::stringstream originalX, originalY, sampledX, sampledY;
for (int i = 0; i < inputSize; ++i) {
originalX << xCoordinates[i];
originalY << yCoordinates[i];
if (i != inputSize - 1) {
originalX << ";";
originalY << ";";
}
}
AKLOGI("===== sampled points =====");
for (int i = 0; i < mSampledInputSize; ++i) {
if (isGeometric) {
AKLOGI("%d: x = %d, y = %d, time = %d, relative speed = %.4f, beeline speed = %d",
i, mSampledInputXs[i], mSampledInputYs[i], mTimes[i], mSpeedRates[i],
getBeelineSpeedPercentile(i));
}
sampledX << mSampledInputXs[i];
sampledY << mSampledInputYs[i];
if (i != mSampledInputSize - 1) {
sampledX << ";";
sampledY << ";";
}
}
AKLOGI("original points:\n%s, %s,\nsampled points:\n%s, %s,\n",
originalX.str().c_str(), originalY.str().c_str(), sampledX.str().c_str(),
sampledY.str().c_str());
ProximityInfoStateUtils::dump(isGeometric, inputSize, xCoordinates, yCoordinates,
mSampledInputSize, &mSampledInputXs, &mSampledInputYs, &mSpeedRates,
&mBeelineSpeedPercentiles);
}
// end
///////////////////////
@ -198,42 +148,15 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
mTouchPositionCorrectionEnabled = mSampledInputSize > 0 && mHasTouchPositionCorrectionData
&& xCoordinates && yCoordinates;
if (!isGeometric && pointerId == 0) {
for (int i = 0; i < inputSize; ++i) {
mPrimaryInputWord[i] = getPrimaryCodePointAt(i);
}
for (int i = 0; i < mSampledInputSize && mTouchPositionCorrectionEnabled; ++i) {
const int *proximityCodePoints = getProximityCodePointsAt(i);
const int primaryKey = proximityCodePoints[0];
const int x = xCoordinates[i];
const int y = yCoordinates[i];
if (DEBUG_PROXIMITY_CHARS) {
int a = x + y + primaryKey;
a += 0;
AKLOGI("--- Primary = %c, x = %d, y = %d", primaryKey, x, y);
}
for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE && proximityCodePoints[j] > 0;
++j) {
const int currentCodePoint = proximityCodePoints[j];
const float squaredDistance =
hasInputCoordinates() ? calculateNormalizedSquaredDistance(
mProximityInfo->getKeyIndexOf(currentCodePoint), i) :
NOT_A_DISTANCE_FLOAT;
if (squaredDistance >= 0.0f) {
mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] =
(int) (squaredDistance * NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR);
} else {
mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] =
(j == 0) ? EQUIVALENT_CHAR_WITHOUT_DISTANCE_INFO :
PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO;
}
if (DEBUG_PROXIMITY_CHARS) {
AKLOGI("--- Proximity (%d) = %c", j, currentCodePoint);
}
}
ProximityInfoStateUtils::initPrimaryInputWord(
inputSize, mInputProximities, mPrimaryInputWord);
if (mTouchPositionCorrectionEnabled) {
ProximityInfoStateUtils::initNormalizedSquaredDistances(
mProximityInfo, inputSize, xCoordinates, yCoordinates, mInputProximities,
hasInputCoordinates(), &mSampledInputXs, &mSampledInputYs,
mNormalizedSquaredDistances);
}
}
if (DEBUG_GEO_FULL) {
AKLOGI("ProximityState init finished: %d points out of %d", mSampledInputSize, inputSize);
}
@ -244,9 +167,9 @@ bool ProximityInfoState::checkAndReturnIsContinuationPossible(const int inputSiz
const bool isGeometric) const {
if (isGeometric) {
for (int i = 0; i < mSampledInputSize; ++i) {
const int index = mInputIndice[i];
const int index = mSampledInputIndice[i];
if (index > inputSize || xCoordinates[index] != mSampledInputXs[i] ||
yCoordinates[index] != mSampledInputYs[i] || times[index] != mTimes[i]) {
yCoordinates[index] != mSampledInputYs[i] || times[index] != mSampledTimes[i]) {
return false;
}
}
@ -265,26 +188,9 @@ bool ProximityInfoState::checkAndReturnIsContinuationPossible(const int inputSiz
return true;
}
float ProximityInfoState::calculateNormalizedSquaredDistance(
const int keyIndex, const int inputIndex) const {
if (keyIndex == NOT_AN_INDEX) {
return NOT_A_DISTANCE_FLOAT;
}
if (!mProximityInfo->hasSweetSpotData(keyIndex)) {
return NOT_A_DISTANCE_FLOAT;
}
if (NOT_A_COORDINATE == mSampledInputXs[inputIndex]) {
return NOT_A_DISTANCE_FLOAT;
}
const float squaredDistance = calculateSquaredDistanceFromSweetSpotCenter(
keyIndex, inputIndex);
const float squaredRadius = square(mProximityInfo->getSweetSpotRadiiAt(keyIndex));
return squaredDistance / squaredRadius;
}
int ProximityInfoState::getDuration(const int index) const {
if (index >= 0 && index < mSampledInputSize - 1) {
return mTimes[index + 1] - mTimes[index];
return mSampledTimes[index + 1] - mSampledTimes[index];
}
return 0;
}
@ -388,15 +294,6 @@ int ProximityInfoState::getSpaceY() const {
return mProximityInfo->getKeyCenterYOfKeyIdG(keyId);
}
float ProximityInfoState::calculateSquaredDistanceFromSweetSpotCenter(
const int keyIndex, const int inputIndex) const {
const float sweetSpotCenterX = mProximityInfo->getSweetSpotCenterXAt(keyIndex);
const float sweetSpotCenterY = mProximityInfo->getSweetSpotCenterYAt(keyIndex);
const float inputX = static_cast<float>(mSampledInputXs[inputIndex]);
const float inputY = static_cast<float>(mSampledInputYs[inputIndex]);
return square(inputX - sweetSpotCenterX) + square(inputY - sweetSpotCenterY);
}
// Puts possible characters into filter and returns new filter size.
int ProximityInfoState::getAllPossibleChars(
const size_t index, int *const filter, const int filterSize) const {
@ -431,8 +328,8 @@ bool ProximityInfoState::isKeyInSerchKeysAfterIndex(const int index, const int k
}
void ProximityInfoState::popInputData() {
ProximityInfoStateUtils::popInputData(&mSampledInputXs, &mSampledInputYs, &mTimes,
&mLengthCache, &mInputIndice);
ProximityInfoStateUtils::popInputData(&mSampledInputXs, &mSampledInputYs, &mSampledTimes,
&mSampledLengthCache, &mSampledInputIndice);
}
float ProximityInfoState::getDirection(const int index0, const int index1) const {

View File

@ -32,9 +32,7 @@ class ProximityInfo;
class ProximityInfoState {
public:
static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR;
static const float NOT_A_DISTANCE_FLOAT;
static const int NOT_A_CODE;
/////////////////////////////////////////
@ -52,10 +50,11 @@ class ProximityInfoState {
: mProximityInfo(0), mMaxPointToKeyLength(0.0f), mAverageSpeed(0.0f),
mHasTouchPositionCorrectionData(false), mMostCommonKeyWidthSquare(0),
mKeyCount(0), mCellHeight(0), mCellWidth(0), mGridHeight(0), mGridWidth(0),
mIsContinuationPossible(false), mSampledInputXs(), mSampledInputYs(), mTimes(),
mInputIndice(), mLengthCache(), mBeelineSpeedPercentiles(), mDistanceCache_G(),
mSpeedRates(), mDirections(), mCharProbabilities(), mNearKeysVector(),
mSearchKeysVector(), mTouchPositionCorrectionEnabled(false), mSampledInputSize(0) {
mIsContinuationPossible(false), mSampledInputXs(), mSampledInputYs(), mSampledTimes(),
mSampledInputIndice(), mSampledLengthCache(), mBeelineSpeedPercentiles(),
mDistanceCache_G(), mSpeedRates(), mDirections(), mCharProbabilities(),
mNearKeysVector(), mSearchKeysVector(), mTouchPositionCorrectionEnabled(false),
mSampledInputSize(0) {
memset(mInputProximities, 0, sizeof(mInputProximities));
memset(mNormalizedSquaredDistances, 0, sizeof(mNormalizedSquaredDistances));
memset(mPrimaryInputWord, 0, sizeof(mPrimaryInputWord));
@ -144,7 +143,7 @@ class ProximityInfoState {
bool hasSpaceProximity(const int index) const;
int getLengthCache(const int index) const {
return mLengthCache[index];
return mSampledLengthCache[index];
}
bool isContinuationPossible() const {
@ -210,7 +209,6 @@ class ProximityInfoState {
/////////////////////////////////////////
// Defined here //
/////////////////////////////////////////
inline float square(const float x) const { return x * x; }
bool hasInputCoordinates() const {
return mSampledInputXs.size() > 0 && mSampledInputYs.size() > 0;
@ -238,9 +236,9 @@ class ProximityInfoState {
std::vector<int> mSampledInputXs;
std::vector<int> mSampledInputYs;
std::vector<int> mTimes;
std::vector<int> mInputIndice;
std::vector<int> mLengthCache;
std::vector<int> mSampledTimes;
std::vector<int> mSampledInputIndice;
std::vector<int> mSampledLengthCache;
std::vector<int> mBeelineSpeedPercentiles;
std::vector<float> mDistanceCache_G;
std::vector<float> mSpeedRates;

View File

@ -24,6 +24,7 @@
#include "proximity_info_state_utils.h"
namespace latinime {
/* static */ int ProximityInfoStateUtils::updateTouchPoints(const int mostCommonKeyWidth,
const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
const int *const inputProximities, const int *const inputXCoordinates,
@ -126,6 +127,114 @@ namespace latinime {
return getProximityCodePointsAt(inputProximities, index)[0];
}
/* static */ void ProximityInfoStateUtils::initPrimaryInputWord(
const int inputSize, const int *const inputProximities, int *primaryInputWord) {
for (int i = 0; i < inputSize; ++i) {
primaryInputWord[i] = getPrimaryCodePointAt(inputProximities, i);
}
}
/* static */ float ProximityInfoStateUtils::calculateSquaredDistanceFromSweetSpotCenter(
const ProximityInfo *const proximityInfo, const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs, const int keyIndex,
const int inputIndex) {
const float sweetSpotCenterX = proximityInfo->getSweetSpotCenterXAt(keyIndex);
const float sweetSpotCenterY = proximityInfo->getSweetSpotCenterYAt(keyIndex);
const float inputX = static_cast<float>((*sampledInputXs)[inputIndex]);
const float inputY = static_cast<float>((*sampledInputYs)[inputIndex]);
return SQUARE_FLOAT(inputX - sweetSpotCenterX) + SQUARE_FLOAT(inputY - sweetSpotCenterY);
}
/* static */ float ProximityInfoStateUtils::calculateNormalizedSquaredDistance(
const ProximityInfo *const proximityInfo, const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs,
const int keyIndex, const int inputIndex) {
if (keyIndex == NOT_AN_INDEX) {
return ProximityInfoParams::NOT_A_DISTANCE_FLOAT;
}
if (!proximityInfo->hasSweetSpotData(keyIndex)) {
return ProximityInfoParams::NOT_A_DISTANCE_FLOAT;
}
if (NOT_A_COORDINATE == (*sampledInputXs)[inputIndex]) {
return ProximityInfoParams::NOT_A_DISTANCE_FLOAT;
}
const float squaredDistance = calculateSquaredDistanceFromSweetSpotCenter(proximityInfo,
sampledInputXs, sampledInputYs, keyIndex, inputIndex);
const float squaredRadius = SQUARE_FLOAT(proximityInfo->getSweetSpotRadiiAt(keyIndex));
return squaredDistance / squaredRadius;
}
/* static */ void ProximityInfoStateUtils::initNormalizedSquaredDistances(
const ProximityInfo *const proximityInfo, const int inputSize,
const int *inputXCoordinates, const int *inputYCoordinates,
const int *const inputProximities, const bool hasInputCoordinates,
const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs,
int *normalizedSquaredDistances) {
for (int i = 0; i < inputSize; ++i) {
const int *proximityCodePoints = getProximityCodePointsAt(inputProximities, i);
const int primaryKey = proximityCodePoints[0];
const int x = inputXCoordinates[i];
const int y = inputYCoordinates[i];
if (DEBUG_PROXIMITY_CHARS) {
int a = x + y + primaryKey;
a += 0;
AKLOGI("--- Primary = %c, x = %d, y = %d", primaryKey, x, y);
}
for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE && proximityCodePoints[j] > 0;
++j) {
const int currentCodePoint = proximityCodePoints[j];
const float squaredDistance =
hasInputCoordinates ? calculateNormalizedSquaredDistance(
proximityInfo, sampledInputXs, sampledInputYs,
proximityInfo->getKeyIndexOf(currentCodePoint), i) :
ProximityInfoParams::NOT_A_DISTANCE_FLOAT;
if (squaredDistance >= 0.0f) {
normalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] =
(int) (squaredDistance
* ProximityInfoParams::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR);
} else {
normalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] =
(j == 0) ? EQUIVALENT_CHAR_WITHOUT_DISTANCE_INFO :
PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO;
}
if (DEBUG_PROXIMITY_CHARS) {
AKLOGI("--- Proximity (%d) = %c", j, currentCodePoint);
}
}
}
}
/* static */ void ProximityInfoStateUtils::initGeometricDistanceInfos(
const ProximityInfo *const proximityInfo, const int keyCount,
const int sampledInputSize, const int lastSavedInputSize,
const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs,
std::vector<NearKeycodesSet> *nearKeysVector,
std::vector<NearKeycodesSet> *searchKeysVector,
std::vector<float> *distanceCache_G) {
nearKeysVector->resize(sampledInputSize);
searchKeysVector->resize(sampledInputSize);
distanceCache_G->resize(sampledInputSize * keyCount);
for (int i = lastSavedInputSize; i < sampledInputSize; ++i) {
(*nearKeysVector)[i].reset();
(*searchKeysVector)[i].reset();
static const float NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD = 4.0f;
for (int k = 0; k < keyCount; ++k) {
const int index = i * keyCount + k;
const int x = (*sampledInputXs)[i];
const int y = (*sampledInputYs)[i];
const float normalizedSquaredDistance =
proximityInfo->getNormalizedSquaredDistanceFromCenterFloatG(k, x, y);
(*distanceCache_G)[index] = normalizedSquaredDistance;
if (normalizedSquaredDistance < NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD) {
(*nearKeysVector)[i][k] = true;
}
}
}
}
/* static */ void ProximityInfoStateUtils::popInputData(std::vector<int> *sampledInputXs,
std::vector<int> *sampledInputYs, std::vector<int> *sampledInputTimes,
std::vector<int> *sampledLengthCache, std::vector<int> *sampledInputIndice) {
@ -171,7 +280,7 @@ namespace latinime {
if (i > 0 && j < (*sampledInputIndice)[i - 1]) {
break;
}
// TODO: use mLengthCache instead?
// TODO: use mSampledLengthCache instead?
length += getDistanceInt(xCoordinates[j], yCoordinates[j],
xCoordinates[j + 1], yCoordinates[j + 1]);
duration += times[j + 1] - times[j];
@ -473,7 +582,7 @@ namespace latinime {
if (DEBUG_DOUBLE_LETTER) {
AKLOGI("--- (%d, %d) double letter: start = %d, end = %d, dist = %d, time = %d,"
" speed = %f, ave = %f, val = %f, start time = %d, end time = %d",
id, mInputIndice[id], start, end, beelineDistance, time,
id, mSampledInputIndice[id], start, end, beelineDistance, time,
(static_cast<float>(beelineDistance) / static_cast<float>(time)), mAverageSpeed,
((static_cast<float>(beelineDistance) / static_cast<float>(time))
/ mAverageSpeed), adjustedStartTime, adjustedEndTime);
@ -849,4 +958,45 @@ namespace latinime {
}
return true;
}
/* static */ void ProximityInfoStateUtils::dump(const bool isGeometric, const int inputSize,
const int *const inputXCoordinates, const int *const inputYCoordinates,
const int sampledInputSize, const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs,
const std::vector<float> *const sampledSpeedRates,
const std::vector<int> *const sampledBeelineSpeedPercentiles) {
if (DEBUG_GEO_FULL) {
for (int i = 0; i < sampledInputSize; ++i) {
AKLOGI("Sampled(%d): x = %d, y = %d, time = %d", i, mSampledInputXs[i],
mSampledInputYs[i], mSampledTimes ? mSampledTimes[i], -1);
}
}
std::stringstream originalX, originalY, sampledX, sampledY;
for (int i = 0; i < inputSize; ++i) {
originalX << inputXCoordinates[i];
originalY << inputYCoordinates[i];
if (i != inputSize - 1) {
originalX << ";";
originalY << ";";
}
}
AKLOGI("===== sampled points =====");
for (int i = 0; i < sampledInputSize; ++i) {
if (isGeometric) {
AKLOGI("%d: x = %d, y = %d, time = %d, relative speed = %.4f, beeline speed = %d",
i, mSampledInputXs[i], mSampledInputYs[i], mSampledTimes[i], mSpeedRates[i],
getBeelineSpeedPercentile(i));
}
sampledX << (*sampledInputXs)[i];
sampledY << (*sampledInputYs)[i];
if (i != sampledInputSize - 1) {
sampledX << ";";
sampledY << ";";
}
}
AKLOGI("original points:\n%s, %s,\nsampled points:\n%s, %s,\n",
originalX.str().c_str(), originalY.str().c_str(), sampledX.str().c_str(),
sampledY.str().c_str());
}
} // namespace latinime

View File

@ -78,7 +78,29 @@ class ProximityInfoStateUtils {
static float getPointToKeyByIdLength(const float maxPointToKeyLength,
const std::vector<float> *const distanceCache_G, const int keyCount,
const int inputIndex, const int keyId);
static void initGeometricDistanceInfos(
const ProximityInfo *const proximityInfo, const int keyCount,
const int sampledInputSize, const int lastSavedInputSize,
const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs,
std::vector<NearKeycodesSet> *nearKeysVector,
std::vector<NearKeycodesSet> *searchKeysVector,
std::vector<float> *distanceCache_G);
static void initPrimaryInputWord(
const int inputSize, const int *const inputProximities, int *primaryInputWord);
static void initNormalizedSquaredDistances(
const ProximityInfo *const proximityInfo, const int inputSize,
const int *inputXCoordinates, const int *inputYCoordinates,
const int *const inputProximities, const bool hasInputCoordinates,
const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs,
int *normalizedSquaredDistances);
static void dump(const bool isGeometric, const int inputSize,
const int *const inputXCoordinates, const int *const inputYCoordinates,
const int sampledInputSize, const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs,
const std::vector<float> *const sampledSpeedRates,
const std::vector<int> *const sampledBeelineSpeedPercentiles);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoStateUtils);
@ -121,6 +143,13 @@ class ProximityInfoStateUtils {
const int sampledInputSize, const std::vector<int> *const lengthCache,
const int index0, const int index1,
std::vector<hash_map_compat<int, float> > *charProbabilities);
static float calculateSquaredDistanceFromSweetSpotCenter(
const ProximityInfo *const proximityInfo, const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs, const int keyIndex,
const int inputIndex);
static float calculateNormalizedSquaredDistance(
const ProximityInfo *const proximityInfo, const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs, const int keyIndex, const int inputIndex);
};
} // namespace latinime
#endif // LATINIME_PROXIMITY_INFO_STATE_UTILS_H

View File

@ -18,6 +18,7 @@
#define LATINIME_SUGGEST_UTILS_H
#include "defines.h"
#include "proximity_info_params.h"
#include "proximity_info_state.h"
namespace latinime {
@ -35,7 +36,7 @@ class SuggestUtils {
static const float R1 = NEUTRAL_SCORE_SQUARED_RADIUS;
static const float R2 = HALF_SCORE_SQUARED_RADIUS;
const float x = normalizedSquaredDistance / static_cast<float>(
ProximityInfoState::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR);
ProximityInfoParams::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR);
const float factor = max((x < R1)
? (A * (R1 - x) + B * x) / R1
: (B * (R2 - x) + C * (x - R1)) / (R2 - R1), MIN);