Loading native/jni/src/defines.h +2 −0 Original line number Diff line number Diff line Loading @@ -392,6 +392,8 @@ static inline void prof_out(void) { template<typename T> inline T min(T a, T b) { return a < b ? a : b; } template<typename T> inline T max(T a, T b) { return a > b ? a : b; } #define M_PI_F 3.14159265f #define NELEMS(x) (sizeof(x) / sizeof((x)[0])) // The ratio of neutral area radius to sweet spot radius. Loading native/jni/src/geometry_utils.h +0 −57 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ #include "defines.h" #define M_PI_F 3.14159265f #define ROUND_FLOAT_10000(f) ((f) < 1000.0f && (f) > 0.001f) \ ? (floorf((f) * 10000.0f) / 10000.0f) : (f) Loading @@ -29,15 +28,6 @@ namespace latinime { static inline float SQUARE_FLOAT(const float x) { return x * x; } static inline float getSquaredDistanceFloat(const float x1, const float y1, const float x2, const float y2) { return SQUARE_FLOAT(x1 - x2) + SQUARE_FLOAT(y1 - y2); } static AK_FORCE_INLINE int getDistanceInt(const int x1, const int y1, const int x2, const int y2) { return static_cast<int>(hypotf(static_cast<float>(x1 - x2), static_cast<float>(y1 - y2))); } static AK_FORCE_INLINE float getAngle(const int x1, const int y1, const int x2, const int y2) { const int dx = x1 - x2; const int dy = y1 - y2; Loading @@ -54,52 +44,5 @@ static AK_FORCE_INLINE float getAngleDiff(const float a1, const float a2) { } return diff; } static inline float pointToLineSegSquaredDistanceFloat(const float x, const float y, const float x1, const float y1, const float x2, const float y2, const bool extend) { const float ray1x = x - x1; const float ray1y = y - y1; const float ray2x = x2 - x1; const float ray2y = y2 - y1; const float dotProduct = ray1x * ray2x + ray1y * ray2y; const float lineLengthSqr = SQUARE_FLOAT(ray2x) + SQUARE_FLOAT(ray2y); const float projectionLengthSqr = dotProduct / lineLengthSqr; float projectionX; float projectionY; if (!extend && projectionLengthSqr < 0.0f) { projectionX = x1; projectionY = y1; } else if (!extend && projectionLengthSqr > 1.0f) { projectionX = x2; projectionY = y2; } else { projectionX = x1 + projectionLengthSqr * ray2x; projectionY = y1 + projectionLengthSqr * ray2y; } return getSquaredDistanceFloat(x, y, projectionX, projectionY); } // Normal distribution N(u, sigma^2). struct NormalDistribution { public: NormalDistribution(const float u, const float sigma) : mU(u), mSigma(sigma), mPreComputedNonExpPart(1.0f / sqrtf(2.0f * M_PI_F * SQUARE_FLOAT(sigma))), mPreComputedExponentPart(-1.0f / (2.0f * SQUARE_FLOAT(sigma))) {} float getProbabilityDensity(const float x) const { const float shiftedX = x - mU; return mPreComputedNonExpPart * expf(mPreComputedExponentPart * SQUARE_FLOAT(shiftedX)); } private: DISALLOW_IMPLICIT_CONSTRUCTORS(NormalDistribution); const float mU; // mean value const float mSigma; // standard deviation const float mPreComputedNonExpPart; // = 1 / sqrt(2 * PI * sigma^2) const float mPreComputedExponentPart; // = -1 / (2 * sigma^2) }; // struct NormalDistribution } // namespace latinime #endif // LATINIME_GEOMETRY_UTILS_H native/jni/src/proximity_info.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -140,7 +140,8 @@ float ProximityInfo::getNormalizedSquaredDistanceFromCenterFloatG( const float touchX = static_cast<float>(x); const float touchY = static_cast<float>(y); const float keyWidth = static_cast<float>(getMostCommonKeyWidth()); return getSquaredDistanceFloat(centerX, centerY, touchX, touchY) / SQUARE_FLOAT(keyWidth); return ProximityInfoUtils::getSquaredDistanceFloat(centerX, centerY, touchX, touchY) / SQUARE_FLOAT(keyWidth); } int ProximityInfo::getCodePointOf(const int keyIndex) const { Loading @@ -163,7 +164,7 @@ void ProximityInfo::initializeG() { for (int i = 0; i < KEY_COUNT; i++) { mKeyKeyDistancesG[i][i] = 0; for (int j = i + 1; j < KEY_COUNT; j++) { mKeyKeyDistancesG[i][j] = getDistanceInt( mKeyKeyDistancesG[i][j] = ProximityInfoUtils::getDistanceInt( mCenterXsG[i], mCenterYsG[i], mCenterXsG[j], mCenterYsG[j]); mKeyKeyDistancesG[j][i] = mKeyKeyDistancesG[i][j]; } Loading native/jni/src/proximity_info.h +0 −4 Original line number Diff line number Diff line Loading @@ -71,10 +71,6 @@ class ProximityInfo { return MOST_COMMON_KEY_WIDTH_SQUARE; } const char *getLocaleStr() const { return mLocaleStr; } int getKeyCount() const { return KEY_COUNT; } Loading native/jni/src/proximity_info_state.cpp +20 −13 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "geometry_utils.h" #include "proximity_info.h" #include "proximity_info_state.h" #include "proximity_info_utils.h" namespace latinime { Loading @@ -46,7 +47,6 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi mProximityInfo = proximityInfo; mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData(); mMostCommonKeyWidthSquare = proximityInfo->getMostCommonKeyWidthSquare(); mLocaleStr = proximityInfo->getLocaleStr(); mKeyCount = proximityInfo->getKeyCount(); mCellHeight = proximityInfo->getCellHeight(); mCellWidth = proximityInfo->getCellWidth(); Loading Loading @@ -324,7 +324,7 @@ void ProximityInfoState::refreshSpeedRates(const int inputSize, const int *const if (i < mSampledInputSize - 1 && j >= mInputIndice[i + 1]) { break; } length += getDistanceInt(xCoordinates[j], yCoordinates[j], length += ProximityInfoUtils::getDistanceInt(xCoordinates[j], yCoordinates[j], xCoordinates[j + 1], yCoordinates[j + 1]); duration += times[j + 1] - times[j]; } Loading @@ -333,7 +333,7 @@ void ProximityInfoState::refreshSpeedRates(const int inputSize, const int *const break; } // TODO: use mLengthCache instead? length += getDistanceInt(xCoordinates[j], yCoordinates[j], length += ProximityInfoUtils::getDistanceInt(xCoordinates[j], yCoordinates[j], xCoordinates[j + 1], yCoordinates[j + 1]); duration += times[j + 1] - times[j]; } Loading Loading @@ -388,7 +388,8 @@ float ProximityInfoState::calculateBeelineSpeedRate( while (start > 0 && tempBeelineDistance < lookupRadius) { tempTime += times[start] - times[start - 1]; --start; tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[start], yCoordinates[start]); tempBeelineDistance = ProximityInfoUtils::getDistanceInt(x0, y0, xCoordinates[start], yCoordinates[start]); } // Exclusive unless this is an edge point if (start > 0 && start < actualInputIndex) { Loading @@ -401,7 +402,8 @@ float ProximityInfoState::calculateBeelineSpeedRate( while (end < (inputSize - 1) && tempBeelineDistance < lookupRadius) { tempTime += times[end + 1] - times[end]; ++end; tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[end], yCoordinates[end]); tempBeelineDistance = ProximityInfoUtils::getDistanceInt(x0, y0, xCoordinates[end], yCoordinates[end]); } // Exclusive unless this is an edge point if (end > actualInputIndex && end < (inputSize - 1)) { Loading @@ -419,7 +421,7 @@ float ProximityInfoState::calculateBeelineSpeedRate( const int y2 = yCoordinates[start]; const int x3 = xCoordinates[end]; const int y3 = yCoordinates[end]; const int beelineDistance = getDistanceInt(x2, y2, x3, y3); const int beelineDistance = ProximityInfoUtils::getDistanceInt(x2, y2, x3, y3); int adjustedStartTime = times[start]; if (start == 0 && actualInputIndex == 0 && inputSize > 1) { adjustedStartTime += FIRST_POINT_TIME_OFFSET_MILLIS; Loading Loading @@ -539,7 +541,8 @@ float ProximityInfoState::getPointScore( } const int baseSampleRate = mProximityInfo->getMostCommonKeyWidth(); const int distPrev = getDistanceInt(mSampledInputXs.back(), mSampledInputYs.back(), const int distPrev = ProximityInfoUtils::getDistanceInt( mSampledInputXs.back(), mSampledInputYs.back(), mSampledInputXs[size - 2], mSampledInputYs[size - 2]) * DISTANCE_BASE_SCALE; float score = 0.0f; Loading Loading @@ -590,13 +593,15 @@ bool ProximityInfoState::pushTouchPoint(const int inputIndex, const int nodeCode } // Check if the last point should be skipped. if (isLastPoint && size > 0) { if (getDistanceInt(x, y, mSampledInputXs.back(), mSampledInputYs.back()) * LAST_POINT_SKIP_DISTANCE_SCALE < mProximityInfo->getMostCommonKeyWidth()) { if (ProximityInfoUtils::getDistanceInt(x, y, mSampledInputXs.back(), mSampledInputYs.back()) * LAST_POINT_SKIP_DISTANCE_SCALE < mProximityInfo->getMostCommonKeyWidth()) { // This point is not used because it's too close to the previous point. if (DEBUG_GEO_FULL) { AKLOGI("p0: size = %zd, x = %d, y = %d, lx = %d, ly = %d, dist = %d, " "width = %d", size, x, y, mSampledInputXs.back(), mSampledInputYs.back(), getDistanceInt(x, y, mSampledInputXs.back(), mSampledInputYs.back()), ProximityInfoUtils::getDistanceInt(x, y, mSampledInputXs.back(), mSampledInputYs.back()), mProximityInfo->getMostCommonKeyWidth() / LAST_POINT_SKIP_DISTANCE_SCALE); } Loading @@ -616,7 +621,7 @@ bool ProximityInfoState::pushTouchPoint(const int inputIndex, const int nodeCode // Pushing point information. if (size > 0) { mLengthCache.push_back( mLengthCache.back() + getDistanceInt( mLengthCache.back() + ProximityInfoUtils::getDistanceInt( x, y, mSampledInputXs.back(), mSampledInputYs.back())); } else { mLengthCache.push_back(0); Loading Loading @@ -867,7 +872,8 @@ float ProximityInfoState::getLineToKeyDistance( const int keyX = mProximityInfo->getKeyCenterXOfKeyIdG(keyId); const int keyY = mProximityInfo->getKeyCenterYOfKeyIdG(keyId); return pointToLineSegSquaredDistanceFloat(keyX, keyY, x0, y0, x1, y1, extend); return ProximityInfoUtils::pointToLineSegSquaredDistanceFloat( keyX, keyY, x0, y0, x1, y1, extend); } // Updates probabilities of aligning to some keys and skipping. Loading Loading @@ -986,7 +992,8 @@ void ProximityInfoState::updateAlignPointProbabilities(const int start) { MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION); const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate + MIN_STANDERD_DIVIATION; NormalDistribution distribution(CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma); ProximityInfoUtils::NormalDistribution distribution(CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma); static const float PREV_DISTANCE_WEIGHT = 0.5f; static const float NEXT_DISTANCE_WEIGHT = 0.6f; // Summing up probability densities of all near keys. Loading Loading
native/jni/src/defines.h +2 −0 Original line number Diff line number Diff line Loading @@ -392,6 +392,8 @@ static inline void prof_out(void) { template<typename T> inline T min(T a, T b) { return a < b ? a : b; } template<typename T> inline T max(T a, T b) { return a > b ? a : b; } #define M_PI_F 3.14159265f #define NELEMS(x) (sizeof(x) / sizeof((x)[0])) // The ratio of neutral area radius to sweet spot radius. Loading
native/jni/src/geometry_utils.h +0 −57 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ #include "defines.h" #define M_PI_F 3.14159265f #define ROUND_FLOAT_10000(f) ((f) < 1000.0f && (f) > 0.001f) \ ? (floorf((f) * 10000.0f) / 10000.0f) : (f) Loading @@ -29,15 +28,6 @@ namespace latinime { static inline float SQUARE_FLOAT(const float x) { return x * x; } static inline float getSquaredDistanceFloat(const float x1, const float y1, const float x2, const float y2) { return SQUARE_FLOAT(x1 - x2) + SQUARE_FLOAT(y1 - y2); } static AK_FORCE_INLINE int getDistanceInt(const int x1, const int y1, const int x2, const int y2) { return static_cast<int>(hypotf(static_cast<float>(x1 - x2), static_cast<float>(y1 - y2))); } static AK_FORCE_INLINE float getAngle(const int x1, const int y1, const int x2, const int y2) { const int dx = x1 - x2; const int dy = y1 - y2; Loading @@ -54,52 +44,5 @@ static AK_FORCE_INLINE float getAngleDiff(const float a1, const float a2) { } return diff; } static inline float pointToLineSegSquaredDistanceFloat(const float x, const float y, const float x1, const float y1, const float x2, const float y2, const bool extend) { const float ray1x = x - x1; const float ray1y = y - y1; const float ray2x = x2 - x1; const float ray2y = y2 - y1; const float dotProduct = ray1x * ray2x + ray1y * ray2y; const float lineLengthSqr = SQUARE_FLOAT(ray2x) + SQUARE_FLOAT(ray2y); const float projectionLengthSqr = dotProduct / lineLengthSqr; float projectionX; float projectionY; if (!extend && projectionLengthSqr < 0.0f) { projectionX = x1; projectionY = y1; } else if (!extend && projectionLengthSqr > 1.0f) { projectionX = x2; projectionY = y2; } else { projectionX = x1 + projectionLengthSqr * ray2x; projectionY = y1 + projectionLengthSqr * ray2y; } return getSquaredDistanceFloat(x, y, projectionX, projectionY); } // Normal distribution N(u, sigma^2). struct NormalDistribution { public: NormalDistribution(const float u, const float sigma) : mU(u), mSigma(sigma), mPreComputedNonExpPart(1.0f / sqrtf(2.0f * M_PI_F * SQUARE_FLOAT(sigma))), mPreComputedExponentPart(-1.0f / (2.0f * SQUARE_FLOAT(sigma))) {} float getProbabilityDensity(const float x) const { const float shiftedX = x - mU; return mPreComputedNonExpPart * expf(mPreComputedExponentPart * SQUARE_FLOAT(shiftedX)); } private: DISALLOW_IMPLICIT_CONSTRUCTORS(NormalDistribution); const float mU; // mean value const float mSigma; // standard deviation const float mPreComputedNonExpPart; // = 1 / sqrt(2 * PI * sigma^2) const float mPreComputedExponentPart; // = -1 / (2 * sigma^2) }; // struct NormalDistribution } // namespace latinime #endif // LATINIME_GEOMETRY_UTILS_H
native/jni/src/proximity_info.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -140,7 +140,8 @@ float ProximityInfo::getNormalizedSquaredDistanceFromCenterFloatG( const float touchX = static_cast<float>(x); const float touchY = static_cast<float>(y); const float keyWidth = static_cast<float>(getMostCommonKeyWidth()); return getSquaredDistanceFloat(centerX, centerY, touchX, touchY) / SQUARE_FLOAT(keyWidth); return ProximityInfoUtils::getSquaredDistanceFloat(centerX, centerY, touchX, touchY) / SQUARE_FLOAT(keyWidth); } int ProximityInfo::getCodePointOf(const int keyIndex) const { Loading @@ -163,7 +164,7 @@ void ProximityInfo::initializeG() { for (int i = 0; i < KEY_COUNT; i++) { mKeyKeyDistancesG[i][i] = 0; for (int j = i + 1; j < KEY_COUNT; j++) { mKeyKeyDistancesG[i][j] = getDistanceInt( mKeyKeyDistancesG[i][j] = ProximityInfoUtils::getDistanceInt( mCenterXsG[i], mCenterYsG[i], mCenterXsG[j], mCenterYsG[j]); mKeyKeyDistancesG[j][i] = mKeyKeyDistancesG[i][j]; } Loading
native/jni/src/proximity_info.h +0 −4 Original line number Diff line number Diff line Loading @@ -71,10 +71,6 @@ class ProximityInfo { return MOST_COMMON_KEY_WIDTH_SQUARE; } const char *getLocaleStr() const { return mLocaleStr; } int getKeyCount() const { return KEY_COUNT; } Loading
native/jni/src/proximity_info_state.cpp +20 −13 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "geometry_utils.h" #include "proximity_info.h" #include "proximity_info_state.h" #include "proximity_info_utils.h" namespace latinime { Loading @@ -46,7 +47,6 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi mProximityInfo = proximityInfo; mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData(); mMostCommonKeyWidthSquare = proximityInfo->getMostCommonKeyWidthSquare(); mLocaleStr = proximityInfo->getLocaleStr(); mKeyCount = proximityInfo->getKeyCount(); mCellHeight = proximityInfo->getCellHeight(); mCellWidth = proximityInfo->getCellWidth(); Loading Loading @@ -324,7 +324,7 @@ void ProximityInfoState::refreshSpeedRates(const int inputSize, const int *const if (i < mSampledInputSize - 1 && j >= mInputIndice[i + 1]) { break; } length += getDistanceInt(xCoordinates[j], yCoordinates[j], length += ProximityInfoUtils::getDistanceInt(xCoordinates[j], yCoordinates[j], xCoordinates[j + 1], yCoordinates[j + 1]); duration += times[j + 1] - times[j]; } Loading @@ -333,7 +333,7 @@ void ProximityInfoState::refreshSpeedRates(const int inputSize, const int *const break; } // TODO: use mLengthCache instead? length += getDistanceInt(xCoordinates[j], yCoordinates[j], length += ProximityInfoUtils::getDistanceInt(xCoordinates[j], yCoordinates[j], xCoordinates[j + 1], yCoordinates[j + 1]); duration += times[j + 1] - times[j]; } Loading Loading @@ -388,7 +388,8 @@ float ProximityInfoState::calculateBeelineSpeedRate( while (start > 0 && tempBeelineDistance < lookupRadius) { tempTime += times[start] - times[start - 1]; --start; tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[start], yCoordinates[start]); tempBeelineDistance = ProximityInfoUtils::getDistanceInt(x0, y0, xCoordinates[start], yCoordinates[start]); } // Exclusive unless this is an edge point if (start > 0 && start < actualInputIndex) { Loading @@ -401,7 +402,8 @@ float ProximityInfoState::calculateBeelineSpeedRate( while (end < (inputSize - 1) && tempBeelineDistance < lookupRadius) { tempTime += times[end + 1] - times[end]; ++end; tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[end], yCoordinates[end]); tempBeelineDistance = ProximityInfoUtils::getDistanceInt(x0, y0, xCoordinates[end], yCoordinates[end]); } // Exclusive unless this is an edge point if (end > actualInputIndex && end < (inputSize - 1)) { Loading @@ -419,7 +421,7 @@ float ProximityInfoState::calculateBeelineSpeedRate( const int y2 = yCoordinates[start]; const int x3 = xCoordinates[end]; const int y3 = yCoordinates[end]; const int beelineDistance = getDistanceInt(x2, y2, x3, y3); const int beelineDistance = ProximityInfoUtils::getDistanceInt(x2, y2, x3, y3); int adjustedStartTime = times[start]; if (start == 0 && actualInputIndex == 0 && inputSize > 1) { adjustedStartTime += FIRST_POINT_TIME_OFFSET_MILLIS; Loading Loading @@ -539,7 +541,8 @@ float ProximityInfoState::getPointScore( } const int baseSampleRate = mProximityInfo->getMostCommonKeyWidth(); const int distPrev = getDistanceInt(mSampledInputXs.back(), mSampledInputYs.back(), const int distPrev = ProximityInfoUtils::getDistanceInt( mSampledInputXs.back(), mSampledInputYs.back(), mSampledInputXs[size - 2], mSampledInputYs[size - 2]) * DISTANCE_BASE_SCALE; float score = 0.0f; Loading Loading @@ -590,13 +593,15 @@ bool ProximityInfoState::pushTouchPoint(const int inputIndex, const int nodeCode } // Check if the last point should be skipped. if (isLastPoint && size > 0) { if (getDistanceInt(x, y, mSampledInputXs.back(), mSampledInputYs.back()) * LAST_POINT_SKIP_DISTANCE_SCALE < mProximityInfo->getMostCommonKeyWidth()) { if (ProximityInfoUtils::getDistanceInt(x, y, mSampledInputXs.back(), mSampledInputYs.back()) * LAST_POINT_SKIP_DISTANCE_SCALE < mProximityInfo->getMostCommonKeyWidth()) { // This point is not used because it's too close to the previous point. if (DEBUG_GEO_FULL) { AKLOGI("p0: size = %zd, x = %d, y = %d, lx = %d, ly = %d, dist = %d, " "width = %d", size, x, y, mSampledInputXs.back(), mSampledInputYs.back(), getDistanceInt(x, y, mSampledInputXs.back(), mSampledInputYs.back()), ProximityInfoUtils::getDistanceInt(x, y, mSampledInputXs.back(), mSampledInputYs.back()), mProximityInfo->getMostCommonKeyWidth() / LAST_POINT_SKIP_DISTANCE_SCALE); } Loading @@ -616,7 +621,7 @@ bool ProximityInfoState::pushTouchPoint(const int inputIndex, const int nodeCode // Pushing point information. if (size > 0) { mLengthCache.push_back( mLengthCache.back() + getDistanceInt( mLengthCache.back() + ProximityInfoUtils::getDistanceInt( x, y, mSampledInputXs.back(), mSampledInputYs.back())); } else { mLengthCache.push_back(0); Loading Loading @@ -867,7 +872,8 @@ float ProximityInfoState::getLineToKeyDistance( const int keyX = mProximityInfo->getKeyCenterXOfKeyIdG(keyId); const int keyY = mProximityInfo->getKeyCenterYOfKeyIdG(keyId); return pointToLineSegSquaredDistanceFloat(keyX, keyY, x0, y0, x1, y1, extend); return ProximityInfoUtils::pointToLineSegSquaredDistanceFloat( keyX, keyY, x0, y0, x1, y1, extend); } // Updates probabilities of aligning to some keys and skipping. Loading Loading @@ -986,7 +992,8 @@ void ProximityInfoState::updateAlignPointProbabilities(const int start) { MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION); const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate + MIN_STANDERD_DIVIATION; NormalDistribution distribution(CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma); ProximityInfoUtils::NormalDistribution distribution(CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma); static const float PREV_DISTANCE_WEIGHT = 0.5f; static const float NEXT_DISTANCE_WEIGHT = 0.6f; // Summing up probability densities of all near keys. Loading