From d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72e Mon Sep 17 00:00:00 2001 From: Satoshi Kataoka Date: Tue, 22 Jan 2013 17:00:43 +0900 Subject: [PATCH] refactor proximity info state Change-Id: Iaf0c0fb7858358209fa12145777f158e0285bc27 --- native/jni/src/proximity_info_params.cpp | 4 + native/jni/src/proximity_info_params.h | 3 + native/jni/src/proximity_info_state.cpp | 169 ++++-------------- native/jni/src/proximity_info_state.h | 22 ++- native/jni/src/proximity_info_state_utils.cpp | 154 +++++++++++++++- native/jni/src/proximity_info_state_utils.h | 31 +++- native/jni/src/suggest_utils.h | 3 +- 7 files changed, 234 insertions(+), 152 deletions(-) diff --git a/native/jni/src/proximity_info_params.cpp b/native/jni/src/proximity_info_params.cpp index 45f8fb529..d62e090b0 100644 --- a/native/jni/src/proximity_info_params.cpp +++ b/native/jni/src/proximity_info_params.cpp @@ -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 diff --git a/native/jni/src/proximity_info_params.h b/native/jni/src/proximity_info_params.h index e54945e6c..171e6b4de 100644 --- a/native/jni/src/proximity_info_params.h +++ b/native/jni/src/proximity_info_params.h @@ -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 diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp index 45b72eb21..86fe7e10a 100644 --- a/native/jni/src/proximity_info_state.cpp +++ b/native/jni/src/proximity_info_state.cpp @@ -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( @@ -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(mSampledInputXs[inputIndex]); - const float inputY = static_cast(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 { diff --git a/native/jni/src/proximity_info_state.h b/native/jni/src/proximity_info_state.h index f2149e774..8bada277e 100644 --- a/native/jni/src/proximity_info_state.h +++ b/native/jni/src/proximity_info_state.h @@ -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 mSampledInputXs; std::vector mSampledInputYs; - std::vector mTimes; - std::vector mInputIndice; - std::vector mLengthCache; + std::vector mSampledTimes; + std::vector mSampledInputIndice; + std::vector mSampledLengthCache; std::vector mBeelineSpeedPercentiles; std::vector mDistanceCache_G; std::vector mSpeedRates; diff --git a/native/jni/src/proximity_info_state_utils.cpp b/native/jni/src/proximity_info_state_utils.cpp index e5567f7a7..9dd3f0b9a 100644 --- a/native/jni/src/proximity_info_state_utils.cpp +++ b/native/jni/src/proximity_info_state_utils.cpp @@ -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 *const sampledInputXs, + const std::vector *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((*sampledInputXs)[inputIndex]); + const float inputY = static_cast((*sampledInputYs)[inputIndex]); + return SQUARE_FLOAT(inputX - sweetSpotCenterX) + SQUARE_FLOAT(inputY - sweetSpotCenterY); +} + +/* static */ float ProximityInfoStateUtils::calculateNormalizedSquaredDistance( + const ProximityInfo *const proximityInfo, const std::vector *const sampledInputXs, + const std::vector *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 *const sampledInputXs, + const std::vector *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 *const sampledInputXs, + const std::vector *const sampledInputYs, + std::vector *nearKeysVector, + std::vector *searchKeysVector, + std::vector *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 *sampledInputXs, std::vector *sampledInputYs, std::vector *sampledInputTimes, std::vector *sampledLengthCache, std::vector *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(beelineDistance) / static_cast(time)), mAverageSpeed, ((static_cast(beelineDistance) / static_cast(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 *const sampledInputXs, + const std::vector *const sampledInputYs, + const std::vector *const sampledSpeedRates, + const std::vector *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 diff --git a/native/jni/src/proximity_info_state_utils.h b/native/jni/src/proximity_info_state_utils.h index 8241eaf89..b67f82cd6 100644 --- a/native/jni/src/proximity_info_state_utils.h +++ b/native/jni/src/proximity_info_state_utils.h @@ -78,7 +78,29 @@ class ProximityInfoStateUtils { static float getPointToKeyByIdLength(const float maxPointToKeyLength, const std::vector *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 *const sampledInputXs, + const std::vector *const sampledInputYs, + std::vector *nearKeysVector, + std::vector *searchKeysVector, + std::vector *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 *const sampledInputXs, + const std::vector *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 *const sampledInputXs, + const std::vector *const sampledInputYs, + const std::vector *const sampledSpeedRates, + const std::vector *const sampledBeelineSpeedPercentiles); private: DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoStateUtils); @@ -121,6 +143,13 @@ class ProximityInfoStateUtils { const int sampledInputSize, const std::vector *const lengthCache, const int index0, const int index1, std::vector > *charProbabilities); + static float calculateSquaredDistanceFromSweetSpotCenter( + const ProximityInfo *const proximityInfo, const std::vector *const sampledInputXs, + const std::vector *const sampledInputYs, const int keyIndex, + const int inputIndex); + static float calculateNormalizedSquaredDistance( + const ProximityInfo *const proximityInfo, const std::vector *const sampledInputXs, + const std::vector *const sampledInputYs, const int keyIndex, const int inputIndex); }; } // namespace latinime #endif // LATINIME_PROXIMITY_INFO_STATE_UTILS_H diff --git a/native/jni/src/suggest_utils.h b/native/jni/src/suggest_utils.h index 42cc5dea0..7d49cde7e 100644 --- a/native/jni/src/suggest_utils.h +++ b/native/jni/src/suggest_utils.h @@ -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( - 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);