Loading native/src/correction.cpp +47 −36 Original line number Diff line number Diff line Loading @@ -118,9 +118,8 @@ bool Correction::initProcessState(const int outputIndex) { mInputIndex = mCorrectionStates[outputIndex].mInputIndex; mNeedsToTraverseAllNodes = mCorrectionStates[outputIndex].mNeedsToTraverseAllNodes; mEquivalentCharStrongCount = mCorrectionStates[outputIndex].mEquivalentCharStrongCount; mEquivalentCharNormalCount = mCorrectionStates[outputIndex].mEquivalentCharNormalCount; mEquivalentCharWeakCount = mCorrectionStates[outputIndex].mEquivalentCharWeakCount; mSumOfDistance = mCorrectionStates[outputIndex].mSumOfDistance; mEquivalentCharCount = mCorrectionStates[outputIndex].mEquivalentCharCount; mProximityCount = mCorrectionStates[outputIndex].mProximityCount; mTransposedCount = mCorrectionStates[outputIndex].mTransposedCount; mExcessiveCount = mCorrectionStates[outputIndex].mExcessiveCount; Loading Loading @@ -175,9 +174,8 @@ void Correction::incrementOutputIndex() { mCorrectionStates[mOutputIndex].mInputIndex = mInputIndex; mCorrectionStates[mOutputIndex].mNeedsToTraverseAllNodes = mNeedsToTraverseAllNodes; mCorrectionStates[mOutputIndex].mEquivalentCharStrongCount = mEquivalentCharStrongCount; mCorrectionStates[mOutputIndex].mEquivalentCharNormalCount = mEquivalentCharNormalCount; mCorrectionStates[mOutputIndex].mEquivalentCharWeakCount = mEquivalentCharWeakCount; mCorrectionStates[mOutputIndex].mSumOfDistance = mSumOfDistance; mCorrectionStates[mOutputIndex].mEquivalentCharCount = mEquivalentCharCount; mCorrectionStates[mOutputIndex].mProximityCount = mProximityCount; mCorrectionStates[mOutputIndex].mTransposedCount = mTransposedCount; mCorrectionStates[mOutputIndex].mExcessiveCount = mExcessiveCount; Loading Loading @@ -220,9 +218,7 @@ Correction::CorrectionType Correction::processSkipChar( } inline bool isEquivalentChar(ProximityInfo::ProximityType type) { // 'type ProximityInfo::EQUIVALENT_CHAR_WEAK' means that // type == ..._WEAK or type == ..._NORMAL or type == ..._STRONG. return type <= ProximityInfo::EQUIVALENT_CHAR_WEAK; return type == ProximityInfo::EQUIVALENT_CHAR; } Correction::CorrectionType Correction::processCharAndCalcState( Loading Loading @@ -304,7 +300,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( // TODO: Change the limit if we'll allow two or more proximity chars with corrections const bool checkProximityChars = noCorrectionsHappenedSoFar || mProximityCount == 0; const ProximityInfo::ProximityType matchedProximityCharId = secondTransposing ? ProximityInfo::EQUIVALENT_CHAR_NORMAL ? ProximityInfo::EQUIVALENT_CHAR : mProximityInfo->getMatchedProximityId(mInputIndex, c, checkProximityChars); if (ProximityInfo::UNRELATED_CHAR == matchedProximityCharId) { Loading Loading @@ -384,18 +380,14 @@ Correction::CorrectionType Correction::processCharAndCalcState( mMatching = true; } else if (isEquivalentChar(matchedProximityCharId)) { mMatching = true; switch (matchedProximityCharId) { case ProximityInfo::EQUIVALENT_CHAR_STRONG: ++mEquivalentCharStrongCount; break; case ProximityInfo::EQUIVALENT_CHAR_NORMAL: ++mEquivalentCharNormalCount; break; case ProximityInfo::EQUIVALENT_CHAR_WEAK: ++mEquivalentCharWeakCount; break; default: assert(false); ++mEquivalentCharCount; if (mSumOfDistance != NOT_A_DISTANCE) { const int distance = mProximityInfo->getNormalizedSquaredDistance(mInputIndex); if (distance != NOT_A_DISTANCE) { mSumOfDistance += distance; } else { mSumOfDistance = NOT_A_DISTANCE; } } } else if (ProximityInfo::NEAR_PROXIMITY_CHAR == matchedProximityCharId) { mProximityMatching = true; Loading Loading @@ -568,8 +560,8 @@ int Correction::RankingAlgorithm::calculateFinalFreq(const int inputIndex, const const int transposedCount = correction->mTransposedCount / 2; const int excessiveCount = correction->mExcessiveCount + correction->mTransposedCount % 2; const int proximityMatchedCount = correction->mProximityCount; const int equivalentCharStrongCount = correction->mEquivalentCharStrongCount; const int equivalentCharWeakCount = correction->mEquivalentCharWeakCount; const int mSumOfDistance = correction->mSumOfDistance; const int mEquivalentCharCount = correction->mEquivalentCharCount; const bool lastCharExceeded = correction->mLastCharExceeded; const bool useFullEditDistance = correction->mUseFullEditDistance; const int outputLength = outputIndex + 1; Loading Loading @@ -679,18 +671,37 @@ int Correction::RankingAlgorithm::calculateFinalFreq(const int inputIndex, const multiplyRate(WORDS_WITH_PROXIMITY_CHARACTER_DEMOTION_RATE, &finalFreq); } for (int i = 0; i < equivalentCharStrongCount; ++i) { if (DEBUG_DICT_FULL) { LOGI("equivalent char strong"); } multiplyRate(WORDS_WITH_EQUIVALENT_CHAR_STRONG_PROMOTION_RATE, &finalFreq); } for (int i = 0; i < equivalentCharWeakCount; ++i) { if (DEBUG_DICT_FULL) { LOGI("equivalent char weak"); } multiplyRate(WORDS_WITH_EQUIVALENT_CHAR_WEAK_DEMOTION_RATE, &finalFreq); if (CALIBRATE_SCORE_BY_TOUCH_COORDINATES && mEquivalentCharCount > 0 && mSumOfDistance != NOT_A_DISTANCE) { // Let (x, y) be the coordinate of a user's touch, and let c be a key. // Assuming users' touch distribution is gauss distribution, the conditional probability of // the user touching (x, y) given he or she intends to hit c is: // p(x, y | c) = exp(-(x - m_x) / (2 * s^2)) / (sqrt(2 * pi) * s) // * exp(-(y - m_y) / (2 * s^2)) / (sqrt(2 * pi) * s) // where (m_x, m_y) is a mean of touches of c, and s is a variance of touches of c. // If user touches c1, c2, .., cn, the joint distribution is // p(x1, y1 | c1) * p(x2, y2 | c2) * ... * p(xn, yn | cn) // We consider the logarithm of this value, that is // sum_i log p(x_i, y_i | c_i) + const // = sum_i ((x_i - m_x)^2 + (y_i - m_y)^2) / (2 * s^2) + const // Thus, we use the sum of squared distance as a score of the word. static const int UPPER = WORDS_WITH_EQUIVALENT_CHAR_STRONGEST_PROMOTION_RATE; static const int LOWER = WORDS_WITH_EQUIVALENT_CHAR_WEAKEST_DEMOTION_RATE; static const int MIDDLE = 100; static const int SHIFT = ProximityInfo::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2; const int expected = mEquivalentCharCount << SHIFT; // factor is a function as described below: // U\ . // \ . // M \ . // \ . // L \------- . // 0 e // (x-axis is mSumOfDistance, y-axis is rate, // and e, U, M, L are expected, UPPER, MIDDLE, LOWER respectively. const int factor = max((UPPER * expected - (UPPER - MIDDLE) * mSumOfDistance) / expected, LOWER); multiplyRate(factor, &finalFreq); } const int errorCount = adjustedProximityMatchedCount > 0 Loading native/src/correction.h +2 −3 Original line number Diff line number Diff line Loading @@ -127,9 +127,8 @@ private: int mOutputIndex; int mInputIndex; int mEquivalentCharStrongCount; int mEquivalentCharNormalCount; int mEquivalentCharWeakCount; int mEquivalentCharCount; int mSumOfDistance; int mProximityCount; int mExcessiveCount; int mTransposedCount; Loading native/src/correction_state.h +4 −6 Original line number Diff line number Diff line Loading @@ -29,9 +29,8 @@ struct CorrectionState { uint16_t mChildCount; uint8_t mInputIndex; uint8_t mEquivalentCharStrongCount; uint8_t mEquivalentCharNormalCount; uint8_t mEquivalentCharWeakCount; int32_t mSumOfDistance; uint8_t mEquivalentCharCount; uint8_t mProximityCount; uint8_t mTransposedCount; uint8_t mExcessiveCount; Loading Loading @@ -66,9 +65,8 @@ inline static void initCorrectionState(CorrectionState *state, const int rootPos state->mExcessivePos = -1; state->mSkipPos = -1; state->mEquivalentCharStrongCount = 0; state->mEquivalentCharNormalCount = 0; state->mEquivalentCharWeakCount = 0; state->mSumOfDistance = 0; state->mEquivalentCharCount = 0; state->mProximityCount = 0; state->mTransposedCount = 0; state->mExcessiveCount = 0; Loading native/src/defines.h +3 −2 Original line number Diff line number Diff line Loading @@ -162,6 +162,7 @@ static void dumpWord(const unsigned short* word, const int length) { #define NEW_DICTIONARY_HEADER_SIZE 5 #define NOT_VALID_WORD -99 #define NOT_A_CHARACTER -1 #define NOT_A_DISTANCE -1 #define KEYCODE_SPACE ' ' Loading @@ -180,8 +181,8 @@ static void dumpWord(const unsigned short* word, const int length) { #define WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE 75 #define WORDS_WITH_EXCESSIVE_CHARACTER_OUT_OF_PROXIMITY_DEMOTION_RATE 75 #define WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE 60 #define WORDS_WITH_EQUIVALENT_CHAR_STRONG_PROMOTION_RATE 105 #define WORDS_WITH_EQUIVALENT_CHAR_WEAK_DEMOTION_RATE 95 #define WORDS_WITH_EQUIVALENT_CHAR_STRONGEST_PROMOTION_RATE 110 #define WORDS_WITH_EQUIVALENT_CHAR_WEAKEST_DEMOTION_RATE 90 #define FULL_MATCHED_WORDS_PROMOTION_RATE 120 #define WORDS_WITH_PROXIMITY_CHARACTER_DEMOTION_RATE 90 #define WORDS_WITH_MATCH_SKIP_PROMOTION_RATE 105 Loading native/src/proximity_info.cpp +17 −29 Original line number Diff line number Diff line Loading @@ -115,41 +115,42 @@ void ProximityInfo::setInputParams(const int* inputCodes, const int inputLength, } mPrimaryInputWord[inputLength] = 0; for (int i = 0; i < mInputLength; ++i) { mSweetSpotTypes[i] = calculateSweetSpotType(i); float normalizedSquaredDistance = calculateNormalizedSquaredDistance(i); if (normalizedSquaredDistance >= 0.0f) { mNormalizedSquaredDistance[i] = (int)(normalizedSquaredDistance * NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR); } else { mNormalizedSquaredDistance[i] = NOT_A_DISTANCE; } } } inline float square(const float x) { return x * x; } ProximityInfo::SweetSpotType ProximityInfo::calculateSweetSpotType(int index) const { float ProximityInfo::calculateNormalizedSquaredDistance(int index) const { static const float NOT_A_DISTANCE_FLOAT = -1.0f; if (KEY_COUNT == 0 || !mInputXCoordinates || !mInputYCoordinates) { // We do not have the coordinate data return UNKNOWN; return NOT_A_DISTANCE_FLOAT; } const int currentChar = getPrimaryCharAt(index); const unsigned short baseLowerC = Dictionary::toBaseLowerCase(currentChar); if (baseLowerC > MAX_CHAR_CODE) { return UNKNOWN; return NOT_A_DISTANCE_FLOAT; } const int keyIndex = mCodeToKeyIndex[baseLowerC]; if (keyIndex < 0) { return UNKNOWN; return NOT_A_DISTANCE_FLOAT; } const float radius = mSweetSpotRadii[keyIndex]; if (radius <= 0.0) { // When there are no calibration data for a key, // the radius of the key is assigned to zero. return UNKNOWN; return NOT_A_DISTANCE; } const float squaredRadius = square(radius); const float squaredDistance = calculateSquaredDistanceFromSweetSpotCenter(keyIndex, index); if (squaredDistance <= squaredRadius) { return IN_SWEET_SPOT; } if (squaredDistance <= square(NEUTRAL_AREA_RADIUS_RATIO) * squaredRadius) { return IN_NEUTRAL_AREA; } return OUT_OF_NEUTRAL_AREA; return squaredDistance / squaredRadius; } float ProximityInfo::calculateSquaredDistanceFromSweetSpotCenter( Loading Loading @@ -213,22 +214,7 @@ ProximityInfo::ProximityType ProximityInfo::getMatchedProximityId( // The first char in the array is what user typed. If it matches right away, // that means the user typed that same char for this pos. if (firstChar == baseLowerC || firstChar == c) { if (CALIBRATE_SCORE_BY_TOUCH_COORDINATES) { switch (mSweetSpotTypes[index]) { case UNKNOWN: return EQUIVALENT_CHAR_NORMAL; case IN_SWEET_SPOT: return EQUIVALENT_CHAR_STRONG; case IN_NEUTRAL_AREA: return EQUIVALENT_CHAR_NORMAL; case OUT_OF_NEUTRAL_AREA: return EQUIVALENT_CHAR_WEAK; default: assert(false); } } else { return EQUIVALENT_CHAR_NORMAL; } return EQUIVALENT_CHAR; } if (!checkProximityChars) return UNRELATED_CHAR; Loading Loading @@ -266,6 +252,8 @@ bool ProximityInfo::sameAsTyped(const unsigned short *word, int length) const { return true; } const int ProximityInfo::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2; const int ProximityInfo::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR; const int ProximityInfo::MAX_KEY_COUNT_IN_A_KEYBOARD; const int ProximityInfo::MAX_CHAR_CODE; Loading Loading
native/src/correction.cpp +47 −36 Original line number Diff line number Diff line Loading @@ -118,9 +118,8 @@ bool Correction::initProcessState(const int outputIndex) { mInputIndex = mCorrectionStates[outputIndex].mInputIndex; mNeedsToTraverseAllNodes = mCorrectionStates[outputIndex].mNeedsToTraverseAllNodes; mEquivalentCharStrongCount = mCorrectionStates[outputIndex].mEquivalentCharStrongCount; mEquivalentCharNormalCount = mCorrectionStates[outputIndex].mEquivalentCharNormalCount; mEquivalentCharWeakCount = mCorrectionStates[outputIndex].mEquivalentCharWeakCount; mSumOfDistance = mCorrectionStates[outputIndex].mSumOfDistance; mEquivalentCharCount = mCorrectionStates[outputIndex].mEquivalentCharCount; mProximityCount = mCorrectionStates[outputIndex].mProximityCount; mTransposedCount = mCorrectionStates[outputIndex].mTransposedCount; mExcessiveCount = mCorrectionStates[outputIndex].mExcessiveCount; Loading Loading @@ -175,9 +174,8 @@ void Correction::incrementOutputIndex() { mCorrectionStates[mOutputIndex].mInputIndex = mInputIndex; mCorrectionStates[mOutputIndex].mNeedsToTraverseAllNodes = mNeedsToTraverseAllNodes; mCorrectionStates[mOutputIndex].mEquivalentCharStrongCount = mEquivalentCharStrongCount; mCorrectionStates[mOutputIndex].mEquivalentCharNormalCount = mEquivalentCharNormalCount; mCorrectionStates[mOutputIndex].mEquivalentCharWeakCount = mEquivalentCharWeakCount; mCorrectionStates[mOutputIndex].mSumOfDistance = mSumOfDistance; mCorrectionStates[mOutputIndex].mEquivalentCharCount = mEquivalentCharCount; mCorrectionStates[mOutputIndex].mProximityCount = mProximityCount; mCorrectionStates[mOutputIndex].mTransposedCount = mTransposedCount; mCorrectionStates[mOutputIndex].mExcessiveCount = mExcessiveCount; Loading Loading @@ -220,9 +218,7 @@ Correction::CorrectionType Correction::processSkipChar( } inline bool isEquivalentChar(ProximityInfo::ProximityType type) { // 'type ProximityInfo::EQUIVALENT_CHAR_WEAK' means that // type == ..._WEAK or type == ..._NORMAL or type == ..._STRONG. return type <= ProximityInfo::EQUIVALENT_CHAR_WEAK; return type == ProximityInfo::EQUIVALENT_CHAR; } Correction::CorrectionType Correction::processCharAndCalcState( Loading Loading @@ -304,7 +300,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( // TODO: Change the limit if we'll allow two or more proximity chars with corrections const bool checkProximityChars = noCorrectionsHappenedSoFar || mProximityCount == 0; const ProximityInfo::ProximityType matchedProximityCharId = secondTransposing ? ProximityInfo::EQUIVALENT_CHAR_NORMAL ? ProximityInfo::EQUIVALENT_CHAR : mProximityInfo->getMatchedProximityId(mInputIndex, c, checkProximityChars); if (ProximityInfo::UNRELATED_CHAR == matchedProximityCharId) { Loading Loading @@ -384,18 +380,14 @@ Correction::CorrectionType Correction::processCharAndCalcState( mMatching = true; } else if (isEquivalentChar(matchedProximityCharId)) { mMatching = true; switch (matchedProximityCharId) { case ProximityInfo::EQUIVALENT_CHAR_STRONG: ++mEquivalentCharStrongCount; break; case ProximityInfo::EQUIVALENT_CHAR_NORMAL: ++mEquivalentCharNormalCount; break; case ProximityInfo::EQUIVALENT_CHAR_WEAK: ++mEquivalentCharWeakCount; break; default: assert(false); ++mEquivalentCharCount; if (mSumOfDistance != NOT_A_DISTANCE) { const int distance = mProximityInfo->getNormalizedSquaredDistance(mInputIndex); if (distance != NOT_A_DISTANCE) { mSumOfDistance += distance; } else { mSumOfDistance = NOT_A_DISTANCE; } } } else if (ProximityInfo::NEAR_PROXIMITY_CHAR == matchedProximityCharId) { mProximityMatching = true; Loading Loading @@ -568,8 +560,8 @@ int Correction::RankingAlgorithm::calculateFinalFreq(const int inputIndex, const const int transposedCount = correction->mTransposedCount / 2; const int excessiveCount = correction->mExcessiveCount + correction->mTransposedCount % 2; const int proximityMatchedCount = correction->mProximityCount; const int equivalentCharStrongCount = correction->mEquivalentCharStrongCount; const int equivalentCharWeakCount = correction->mEquivalentCharWeakCount; const int mSumOfDistance = correction->mSumOfDistance; const int mEquivalentCharCount = correction->mEquivalentCharCount; const bool lastCharExceeded = correction->mLastCharExceeded; const bool useFullEditDistance = correction->mUseFullEditDistance; const int outputLength = outputIndex + 1; Loading Loading @@ -679,18 +671,37 @@ int Correction::RankingAlgorithm::calculateFinalFreq(const int inputIndex, const multiplyRate(WORDS_WITH_PROXIMITY_CHARACTER_DEMOTION_RATE, &finalFreq); } for (int i = 0; i < equivalentCharStrongCount; ++i) { if (DEBUG_DICT_FULL) { LOGI("equivalent char strong"); } multiplyRate(WORDS_WITH_EQUIVALENT_CHAR_STRONG_PROMOTION_RATE, &finalFreq); } for (int i = 0; i < equivalentCharWeakCount; ++i) { if (DEBUG_DICT_FULL) { LOGI("equivalent char weak"); } multiplyRate(WORDS_WITH_EQUIVALENT_CHAR_WEAK_DEMOTION_RATE, &finalFreq); if (CALIBRATE_SCORE_BY_TOUCH_COORDINATES && mEquivalentCharCount > 0 && mSumOfDistance != NOT_A_DISTANCE) { // Let (x, y) be the coordinate of a user's touch, and let c be a key. // Assuming users' touch distribution is gauss distribution, the conditional probability of // the user touching (x, y) given he or she intends to hit c is: // p(x, y | c) = exp(-(x - m_x) / (2 * s^2)) / (sqrt(2 * pi) * s) // * exp(-(y - m_y) / (2 * s^2)) / (sqrt(2 * pi) * s) // where (m_x, m_y) is a mean of touches of c, and s is a variance of touches of c. // If user touches c1, c2, .., cn, the joint distribution is // p(x1, y1 | c1) * p(x2, y2 | c2) * ... * p(xn, yn | cn) // We consider the logarithm of this value, that is // sum_i log p(x_i, y_i | c_i) + const // = sum_i ((x_i - m_x)^2 + (y_i - m_y)^2) / (2 * s^2) + const // Thus, we use the sum of squared distance as a score of the word. static const int UPPER = WORDS_WITH_EQUIVALENT_CHAR_STRONGEST_PROMOTION_RATE; static const int LOWER = WORDS_WITH_EQUIVALENT_CHAR_WEAKEST_DEMOTION_RATE; static const int MIDDLE = 100; static const int SHIFT = ProximityInfo::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2; const int expected = mEquivalentCharCount << SHIFT; // factor is a function as described below: // U\ . // \ . // M \ . // \ . // L \------- . // 0 e // (x-axis is mSumOfDistance, y-axis is rate, // and e, U, M, L are expected, UPPER, MIDDLE, LOWER respectively. const int factor = max((UPPER * expected - (UPPER - MIDDLE) * mSumOfDistance) / expected, LOWER); multiplyRate(factor, &finalFreq); } const int errorCount = adjustedProximityMatchedCount > 0 Loading
native/src/correction.h +2 −3 Original line number Diff line number Diff line Loading @@ -127,9 +127,8 @@ private: int mOutputIndex; int mInputIndex; int mEquivalentCharStrongCount; int mEquivalentCharNormalCount; int mEquivalentCharWeakCount; int mEquivalentCharCount; int mSumOfDistance; int mProximityCount; int mExcessiveCount; int mTransposedCount; Loading
native/src/correction_state.h +4 −6 Original line number Diff line number Diff line Loading @@ -29,9 +29,8 @@ struct CorrectionState { uint16_t mChildCount; uint8_t mInputIndex; uint8_t mEquivalentCharStrongCount; uint8_t mEquivalentCharNormalCount; uint8_t mEquivalentCharWeakCount; int32_t mSumOfDistance; uint8_t mEquivalentCharCount; uint8_t mProximityCount; uint8_t mTransposedCount; uint8_t mExcessiveCount; Loading Loading @@ -66,9 +65,8 @@ inline static void initCorrectionState(CorrectionState *state, const int rootPos state->mExcessivePos = -1; state->mSkipPos = -1; state->mEquivalentCharStrongCount = 0; state->mEquivalentCharNormalCount = 0; state->mEquivalentCharWeakCount = 0; state->mSumOfDistance = 0; state->mEquivalentCharCount = 0; state->mProximityCount = 0; state->mTransposedCount = 0; state->mExcessiveCount = 0; Loading
native/src/defines.h +3 −2 Original line number Diff line number Diff line Loading @@ -162,6 +162,7 @@ static void dumpWord(const unsigned short* word, const int length) { #define NEW_DICTIONARY_HEADER_SIZE 5 #define NOT_VALID_WORD -99 #define NOT_A_CHARACTER -1 #define NOT_A_DISTANCE -1 #define KEYCODE_SPACE ' ' Loading @@ -180,8 +181,8 @@ static void dumpWord(const unsigned short* word, const int length) { #define WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE 75 #define WORDS_WITH_EXCESSIVE_CHARACTER_OUT_OF_PROXIMITY_DEMOTION_RATE 75 #define WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE 60 #define WORDS_WITH_EQUIVALENT_CHAR_STRONG_PROMOTION_RATE 105 #define WORDS_WITH_EQUIVALENT_CHAR_WEAK_DEMOTION_RATE 95 #define WORDS_WITH_EQUIVALENT_CHAR_STRONGEST_PROMOTION_RATE 110 #define WORDS_WITH_EQUIVALENT_CHAR_WEAKEST_DEMOTION_RATE 90 #define FULL_MATCHED_WORDS_PROMOTION_RATE 120 #define WORDS_WITH_PROXIMITY_CHARACTER_DEMOTION_RATE 90 #define WORDS_WITH_MATCH_SKIP_PROMOTION_RATE 105 Loading
native/src/proximity_info.cpp +17 −29 Original line number Diff line number Diff line Loading @@ -115,41 +115,42 @@ void ProximityInfo::setInputParams(const int* inputCodes, const int inputLength, } mPrimaryInputWord[inputLength] = 0; for (int i = 0; i < mInputLength; ++i) { mSweetSpotTypes[i] = calculateSweetSpotType(i); float normalizedSquaredDistance = calculateNormalizedSquaredDistance(i); if (normalizedSquaredDistance >= 0.0f) { mNormalizedSquaredDistance[i] = (int)(normalizedSquaredDistance * NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR); } else { mNormalizedSquaredDistance[i] = NOT_A_DISTANCE; } } } inline float square(const float x) { return x * x; } ProximityInfo::SweetSpotType ProximityInfo::calculateSweetSpotType(int index) const { float ProximityInfo::calculateNormalizedSquaredDistance(int index) const { static const float NOT_A_DISTANCE_FLOAT = -1.0f; if (KEY_COUNT == 0 || !mInputXCoordinates || !mInputYCoordinates) { // We do not have the coordinate data return UNKNOWN; return NOT_A_DISTANCE_FLOAT; } const int currentChar = getPrimaryCharAt(index); const unsigned short baseLowerC = Dictionary::toBaseLowerCase(currentChar); if (baseLowerC > MAX_CHAR_CODE) { return UNKNOWN; return NOT_A_DISTANCE_FLOAT; } const int keyIndex = mCodeToKeyIndex[baseLowerC]; if (keyIndex < 0) { return UNKNOWN; return NOT_A_DISTANCE_FLOAT; } const float radius = mSweetSpotRadii[keyIndex]; if (radius <= 0.0) { // When there are no calibration data for a key, // the radius of the key is assigned to zero. return UNKNOWN; return NOT_A_DISTANCE; } const float squaredRadius = square(radius); const float squaredDistance = calculateSquaredDistanceFromSweetSpotCenter(keyIndex, index); if (squaredDistance <= squaredRadius) { return IN_SWEET_SPOT; } if (squaredDistance <= square(NEUTRAL_AREA_RADIUS_RATIO) * squaredRadius) { return IN_NEUTRAL_AREA; } return OUT_OF_NEUTRAL_AREA; return squaredDistance / squaredRadius; } float ProximityInfo::calculateSquaredDistanceFromSweetSpotCenter( Loading Loading @@ -213,22 +214,7 @@ ProximityInfo::ProximityType ProximityInfo::getMatchedProximityId( // The first char in the array is what user typed. If it matches right away, // that means the user typed that same char for this pos. if (firstChar == baseLowerC || firstChar == c) { if (CALIBRATE_SCORE_BY_TOUCH_COORDINATES) { switch (mSweetSpotTypes[index]) { case UNKNOWN: return EQUIVALENT_CHAR_NORMAL; case IN_SWEET_SPOT: return EQUIVALENT_CHAR_STRONG; case IN_NEUTRAL_AREA: return EQUIVALENT_CHAR_NORMAL; case OUT_OF_NEUTRAL_AREA: return EQUIVALENT_CHAR_WEAK; default: assert(false); } } else { return EQUIVALENT_CHAR_NORMAL; } return EQUIVALENT_CHAR; } if (!checkProximityChars) return UNRELATED_CHAR; Loading Loading @@ -266,6 +252,8 @@ bool ProximityInfo::sameAsTyped(const unsigned short *word, int length) const { return true; } const int ProximityInfo::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2; const int ProximityInfo::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR; const int ProximityInfo::MAX_KEY_COUNT_IN_A_KEYBOARD; const int ProximityInfo::MAX_CHAR_CODE; Loading