Loading native/jni/src/proximity_info_params.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -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 native/jni/src/proximity_info_params.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 native/jni/src/proximity_info_state.cpp +33 −136 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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(); Loading @@ -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(); Loading @@ -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>( Loading @@ -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]; Loading @@ -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 /////////////////////// Loading @@ -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); } Loading @@ -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; } } Loading @@ -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; } Loading Loading @@ -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 { Loading Loading @@ -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 { Loading native/jni/src/proximity_info_state.h +10 −12 Original line number Diff line number Diff line Loading @@ -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; ///////////////////////////////////////// Loading @@ -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)); Loading Loading @@ -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 { Loading Loading @@ -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; Loading Loading @@ -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; Loading native/jni/src/proximity_info_state_utils.cpp +152 −2 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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]; Loading Loading @@ -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); Loading Loading @@ -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 Loading
native/jni/src/proximity_info_params.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -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
native/jni/src/proximity_info_params.h +3 −0 Original line number Diff line number Diff line Loading @@ -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
native/jni/src/proximity_info_state.cpp +33 −136 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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(); Loading @@ -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(); Loading @@ -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>( Loading @@ -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]; Loading @@ -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 /////////////////////// Loading @@ -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); } Loading @@ -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; } } Loading @@ -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; } Loading Loading @@ -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 { Loading Loading @@ -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 { Loading
native/jni/src/proximity_info_state.h +10 −12 Original line number Diff line number Diff line Loading @@ -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; ///////////////////////////////////////// Loading @@ -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)); Loading Loading @@ -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 { Loading Loading @@ -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; Loading Loading @@ -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; Loading
native/jni/src/proximity_info_state_utils.cpp +152 −2 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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]; Loading Loading @@ -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); Loading Loading @@ -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