Loading native/jni/src/correction.cpp +27 −26 Original line number Diff line number Diff line Loading @@ -98,7 +98,7 @@ inline static int getCurrentEditDistance(int *editDistanceTable, const int editD static const char QUOTE = '\''; inline bool Correction::isQuote(const unsigned short c) { const unsigned short userTypedChar = mProximityInfo->getPrimaryCharAt(mInputIndex); const unsigned short userTypedChar = mProximityInfoState.getPrimaryCharAt(mInputIndex); return (c == QUOTE && userTypedChar != QUOTE); } Loading Loading @@ -283,7 +283,7 @@ bool Correction::needsToPrune() const { void Correction::addCharToCurrentWord(const int32_t c) { mWord[mOutputIndex] = c; const unsigned short *primaryInputWord = mProximityInfo->getPrimaryInputWord(); const unsigned short *primaryInputWord = mProximityInfoState.getPrimaryInputWord(); calcEditDistanceOneStep(mEditDistanceTable, primaryInputWord, mInputLength, mWord, mOutputIndex + 1); } Loading Loading @@ -335,19 +335,19 @@ Correction::CorrectionType Correction::processCharAndCalcState( bool incremented = false; if (mLastCharExceeded && mInputIndex == mInputLength - 1) { // TODO: Do not check the proximity if EditDistance exceeds the threshold const ProximityType matchId = mProximityInfo->getMatchedProximityId(mInputIndex, c, true, &proximityIndex); const ProximityType matchId = mProximityInfoState.getMatchedProximityId( mInputIndex, c, true, &proximityIndex); if (isEquivalentChar(matchId)) { mLastCharExceeded = false; --mExcessiveCount; mDistances[mOutputIndex] = mProximityInfo->getNormalizedSquaredDistance(mInputIndex, 0); mProximityInfoState.getNormalizedSquaredDistance(mInputIndex, 0); } else if (matchId == NEAR_PROXIMITY_CHAR) { mLastCharExceeded = false; --mExcessiveCount; ++mProximityCount; mDistances[mOutputIndex] = mProximityInfo->getNormalizedSquaredDistance(mInputIndex, proximityIndex); mDistances[mOutputIndex] = mProximityInfoState.getNormalizedSquaredDistance( mInputIndex, proximityIndex); } if (!isQuote(c)) { incrementInputIndex(); Loading Loading @@ -388,7 +388,8 @@ Correction::CorrectionType Correction::processCharAndCalcState( bool secondTransposing = false; if (mTransposedCount % 2 == 1) { if (isEquivalentChar(mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false))) { if (isEquivalentChar(mProximityInfoState.getMatchedProximityId( mInputIndex - 1, c, false))) { ++mTransposedCount; secondTransposing = true; } else if (mCorrectionStates[mOutputIndex].mExceeding) { Loading Loading @@ -419,7 +420,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( ProximityType matchedProximityCharId = secondTransposing ? EQUIVALENT_CHAR : mProximityInfo->getMatchedProximityId( : mProximityInfoState.getMatchedProximityId( mInputIndex, c, checkProximityChars, &proximityIndex); if (UNRELATED_CHAR == matchedProximityCharId Loading @@ -427,7 +428,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( if (canTryCorrection && mOutputIndex > 0 && mCorrectionStates[mOutputIndex].mProximityMatching && mCorrectionStates[mOutputIndex].mExceeding && isEquivalentChar(mProximityInfo->getMatchedProximityId( && isEquivalentChar(mProximityInfoState.getMatchedProximityId( mInputIndex, mWord[mOutputIndex - 1], false))) { if (DEBUG_CORRECTION && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) Loading @@ -446,7 +447,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( // Here, we are doing something equivalent to matchedProximityCharId, // but we already know that "excessive char correction" just happened // so that we just need to check "mProximityCount == 0". matchedProximityCharId = mProximityInfo->getMatchedProximityId( matchedProximityCharId = mProximityInfoState.getMatchedProximityId( mInputIndex, c, mProximityCount == 0, &proximityIndex); } } Loading @@ -463,10 +464,10 @@ Correction::CorrectionType Correction::processCharAndCalcState( if (mInputIndex < mInputLength - 1 && mOutputIndex > 0 && mTransposedCount > 0 && !mCorrectionStates[mOutputIndex].mTransposing && mCorrectionStates[mOutputIndex - 1].mTransposing && isEquivalentChar(mProximityInfo->getMatchedProximityId( && isEquivalentChar(mProximityInfoState.getMatchedProximityId( mInputIndex, mWord[mOutputIndex - 1], false)) && isEquivalentChar( mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false))) { mProximityInfoState.getMatchedProximityId(mInputIndex + 1, c, false))) { // Conversion t->e // Example: // occaisional -> occa sional Loading @@ -478,7 +479,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( && !mCorrectionStates[mOutputIndex].mTransposing && mCorrectionStates[mOutputIndex - 1].mTransposing && isEquivalentChar( mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false))) { mProximityInfoState.getMatchedProximityId(mInputIndex - 1, c, false))) { // Conversion t->s // Example: // chcolate -> chocolate Loading @@ -490,7 +491,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( && mCorrectionStates[mOutputIndex].mProximityMatching && mCorrectionStates[mOutputIndex].mSkipping && isEquivalentChar( mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false))) { mProximityInfoState.getMatchedProximityId(mInputIndex - 1, c, false))) { // Conversion p->s // Note: This logic tries saving cases like contrst --> contrast -- "a" is one of // proximity chars of "s", but it should rather be handled as a skipped char. Loading @@ -502,7 +503,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( && mCorrectionStates[mOutputIndex].mSkipping && mCorrectionStates[mOutputIndex].mAdditionalProximityMatching && isProximityCharOrEquivalentChar( mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false))) { mProximityInfoState.getMatchedProximityId(mInputIndex + 1, c, false))) { // Conversion s->a incrementInputIndex(); --mSkippedCount; Loading @@ -511,7 +512,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( mDistances[mOutputIndex] = ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO; } else if ((mExceeding || mTransposing) && mInputIndex - 1 < mInputLength && isEquivalentChar( mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false))) { mProximityInfoState.getMatchedProximityId(mInputIndex + 1, c, false))) { // 1.2. Excessive or transpose correction if (mTransposing) { ++mTransposedCount; Loading Loading @@ -573,12 +574,12 @@ Correction::CorrectionType Correction::processCharAndCalcState( } else if (isEquivalentChar(matchedProximityCharId)) { mMatching = true; ++mEquivalentCharCount; mDistances[mOutputIndex] = mProximityInfo->getNormalizedSquaredDistance(mInputIndex, 0); mDistances[mOutputIndex] = mProximityInfoState.getNormalizedSquaredDistance(mInputIndex, 0); } else if (NEAR_PROXIMITY_CHAR == matchedProximityCharId) { mProximityMatching = true; ++mProximityCount; mDistances[mOutputIndex] = mProximityInfo->getNormalizedSquaredDistance(mInputIndex, proximityIndex); mProximityInfoState.getNormalizedSquaredDistance(mInputIndex, proximityIndex); if (DEBUG_CORRECTION && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 Loading Loading @@ -662,7 +663,7 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex const int excessivePos = correction->getExcessivePos(); const int typedLetterMultiplier = correction->TYPED_LETTER_MULTIPLIER; const int fullWordMultiplier = correction->FULL_WORD_MULTIPLIER; const ProximityInfo *proximityInfo = correction->mProximityInfo; const ProximityInfoState *proximityInfoState = &correction->mProximityInfoState; const int skippedCount = correction->mSkippedCount; const int transposedCount = correction->mTransposedCount / 2; const int excessiveCount = correction->mExcessiveCount + correction->mTransposedCount % 2; Loading @@ -685,7 +686,7 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex const bool skipped = skippedCount > 0; const int quoteDiffCount = max(0, getQuoteCount(word, outputLength) - getQuoteCount(proximityInfo->getPrimaryInputWord(), inputLength)); - getQuoteCount(proximityInfoState->getPrimaryInputWord(), inputLength)); // TODO: Calculate edit distance for transposed and excessive int ed = 0; Loading Loading @@ -737,7 +738,7 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex multiplyIntCapped(matchWeight, &finalFreq); } if (proximityInfo->getMatchedProximityId(0, word[0], true) == UNRELATED_CHAR) { if (proximityInfoState->getMatchedProximityId(0, word[0], true) == UNRELATED_CHAR) { multiplyRate(FIRST_CHAR_DIFFERENT_DEMOTION_RATE, &finalFreq); } Loading @@ -763,7 +764,7 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex // Demotion for a word with excessive character if (excessiveCount > 0) { multiplyRate(WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE, &finalFreq); if (!lastCharExceeded && !proximityInfo->existsAdjacentProximityChars(excessivePos)) { if (!lastCharExceeded && !proximityInfoState->existsAdjacentProximityChars(excessivePos)) { if (DEBUG_DICT_FULL) { AKLOGI("Double excessive demotion"); } Loading @@ -774,7 +775,8 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex } const bool performTouchPositionCorrection = CALIBRATE_SCORE_BY_TOUCH_COORDINATES && proximityInfo->touchPositionCorrectionEnabled() CALIBRATE_SCORE_BY_TOUCH_COORDINATES && proximityInfoState->touchPositionCorrectionEnabled() && skippedCount == 0 && excessiveCount == 0 && transposedCount == 0; // Score calibration by touch coordinates is being done only for pure-fat finger typing error // cases. Loading Loading @@ -1145,5 +1147,4 @@ float Correction::RankingAlgorithm::calcNormalizedScore(const unsigned short* be const float weight = 1.0 - (float) distance / afterLength; return (score / maxScore) * weight; } } // namespace latinime native/jni/src/correction.h +18 −2 Original line number Diff line number Diff line Loading @@ -19,9 +19,10 @@ #include <assert.h> #include <stdint.h> #include "correction_state.h" #include "correction_state.h" #include "defines.h" #include "proximity_info_state.h" namespace latinime { Loading Loading @@ -178,6 +179,21 @@ class Correction { static const int FULL_WORD_MULTIPLIER = 2; }; // proximity info state void initInputParams(const ProximityInfo *proximityInfo, const int32_t *inputCodes, const int inputLength, const int *xCoordinates, const int *yCoordinates) { mProximityInfoState.initInputParams( proximityInfo, inputCodes, inputLength, xCoordinates, yCoordinates); } const unsigned short* getPrimaryInputWord() const { return mProximityInfoState.getPrimaryInputWord(); } unsigned short getPrimaryCharAt(const int index) const { return mProximityInfoState.getPrimaryCharAt(index); } private: inline void incrementInputIndex(); inline void incrementOutputIndex(); Loading Loading @@ -240,7 +256,7 @@ class Correction { bool mExceeding; bool mTransposing; bool mSkipping; ProximityInfoState mProximityInfoState; }; } // namespace latinime #endif // LATINIME_CORRECTION_H native/jni/src/proximity_info.cpp +0 −53 Original line number Diff line number Diff line Loading @@ -73,9 +73,6 @@ ProximityInfo::ProximityInfo(const std::string localeStr, const int maxProximity copyOrFillZero(mSweetSpotRadii, sweetSpotRadii, KEY_COUNT * sizeof(mSweetSpotRadii[0])); initializeCodeToKeyIndex(); mProximityInfoState = new ProximityInfoState(this, MAX_PROXIMITY_CHARS_SIZE, HAS_TOUCH_POSITION_CORRECTION_DATA, MOST_COMMON_KEY_WIDTH_SQUARE, mLocaleStr, KEY_COUNT, CELL_HEIGHT, CELL_WIDTH, GRID_WIDTH, GRID_HEIGHT); } // Build the reversed look up table from the char code to the index in mKeyXCoordinates, Loading @@ -92,7 +89,6 @@ void ProximityInfo::initializeCodeToKeyIndex() { ProximityInfo::~ProximityInfo() { delete[] mProximityCharsArray; delete mProximityInfoState; } inline int ProximityInfo::getStartIndexFromCoordinates(const int x, const int y) const { Loading Loading @@ -203,12 +199,6 @@ void ProximityInfo::calculateNearbyKeyCodes( } } // TODO: remove void ProximityInfo::initInputParams(const int32_t *inputCodes, const int inputLength, const int *xCoordinates, const int *yCoordinates) { mProximityInfoState->initInputParams(inputCodes, inputLength, xCoordinates, yCoordinates); } int ProximityInfo::getKeyIndex(const int c) const { if (KEY_COUNT == 0) { // We do not have the coordinate data Loading @@ -220,47 +210,4 @@ int ProximityInfo::getKeyIndex(const int c) const { } return mCodeToKeyIndex[baseLowerC]; } // TODO: remove inline const int* ProximityInfo::getProximityCharsAt(const int index) const { return mProximityInfoState->getProximityCharsAt(index); } // TODO: remove unsigned short ProximityInfo::getPrimaryCharAt(const int index) const { return mProximityInfoState->getPrimaryCharAt(index); } // TODO: remove bool ProximityInfo::existsCharInProximityAt(const int index, const int c) const { return mProximityInfoState->existsCharInProximityAt(index, c); } // TODO: remove bool ProximityInfo::existsAdjacentProximityChars(const int index) const { return mProximityInfoState->existsAdjacentProximityChars(index); } // TODO: remove ProximityType ProximityInfo::getMatchedProximityId(const int index, const unsigned short c, const bool checkProximityChars, int *proximityIndex) const { return mProximityInfoState->getMatchedProximityId( index, c, checkProximityChars, proximityIndex); } // TODO: remove int ProximityInfo::getNormalizedSquaredDistance( const int inputIndex, const int proximityIndex) const { return mProximityInfoState->getNormalizedSquaredDistance(inputIndex, proximityIndex); } // TODO: remove const unsigned short* ProximityInfo::getPrimaryInputWord() const { return mProximityInfoState->getPrimaryInputWord(); } // TODO: remove bool ProximityInfo::touchPositionCorrectionEnabled() const { return mProximityInfoState->touchPositionCorrectionEnabled(); } } // namespace latinime native/jni/src/proximity_info.h +31 −18 Original line number Diff line number Diff line Loading @@ -25,11 +25,9 @@ namespace latinime { class Correction; class ProximityInfoState; class ProximityInfo { public: ProximityInfo(const std::string localeStr, const int maxProximityCharsSize, const int keyboardWidth, const int keyboardHeight, const int gridWidth, const int gridHeight, const int mostCommonkeyWidth, Loading Loading @@ -68,21 +66,37 @@ class ProximityInfo { void calculateNearbyKeyCodes( const int x, const int y, const int32_t primaryKey, int *inputCodes) const; //////////////////////////////////// // Access to proximity info state // // TODO: remove // //////////////////////////////////// void initInputParams(const int32_t *inputCodes, const int inputLength, const int *xCoordinates, const int *yCoordinates); const int* getProximityCharsAt(const int index) const; unsigned short getPrimaryCharAt(const int index) const; bool existsCharInProximityAt(const int index, const int c) const; bool existsAdjacentProximityChars(const int index) const; ProximityType getMatchedProximityId(const int index, const unsigned short c, const bool checkProximityChars, int *proximityIndex = 0) const; const unsigned short* getPrimaryInputWord() const; bool touchPositionCorrectionEnabled() const; //////////////////////////////////// bool hasTouchPositionCorrectionData() const { return HAS_TOUCH_POSITION_CORRECTION_DATA; } int getMostCommonKeyWidthSquare() const { return MOST_COMMON_KEY_WIDTH_SQUARE; } std::string getLocaleStr() const { return mLocaleStr; } int getKeyCount() const { return KEY_COUNT; } int getCellHeight() const { return CELL_HEIGHT; } int getCellWidth() const { return CELL_WIDTH; } int getGridWidth() const { return GRID_WIDTH; } int getGridHeight() const { return GRID_HEIGHT; } private: // The max number of the keys in one keyboard layout Loading Loading @@ -121,7 +135,6 @@ class ProximityInfo { float mSweetSpotRadii[MAX_KEY_COUNT_IN_A_KEYBOARD]; int mCodeToKeyIndex[MAX_CHAR_CODE + 1]; // TODO: move to correction.h ProximityInfoState *mProximityInfoState; }; } // namespace latinime Loading native/jni/src/proximity_info_state.cpp +53 −11 Original line number Diff line number Diff line Loading @@ -27,25 +27,41 @@ #include "proximity_info_state.h" namespace latinime { void ProximityInfoState::initInputParams(const int32_t* inputCodes, const int inputLength, void ProximityInfoState::initInputParams( const ProximityInfo* proximityInfo, const int32_t* inputCodes, const int inputLength, const int* xCoordinates, const int* yCoordinates) { mProximityInfo = proximityInfo; mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData(); mMostCommonKeyWidthSquare = proximityInfo->getMostCommonKeyWidthSquare(); mLocaleStr = proximityInfo->getLocaleStr(); mKeyCount = proximityInfo->getKeyCount(); mCellHeight = proximityInfo->getCellHeight(); mCellWidth = proximityInfo->getCellWidth(); mGridHeight = proximityInfo->getGridWidth(); mGridWidth = proximityInfo->getGridHeight(); const int normalizedSquaredDistancesLength = MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH_INTERNAL; for (int i = 0; i < normalizedSquaredDistancesLength; ++i) { mNormalizedSquaredDistances[i] = NOT_A_DISTANCE; } memset(mInputCodes, 0, MAX_WORD_LENGTH_INTERNAL * MAX_PROXIMITY_CHARS_SIZE * sizeof(mInputCodes[0])); MAX_WORD_LENGTH_INTERNAL * MAX_PROXIMITY_CHARS_SIZE_INTERNAL * sizeof(mInputCodes[0])); for (int i = 0; i < inputLength; ++i) { const int32_t primaryKey = inputCodes[i]; const int x = xCoordinates[i]; const int y = yCoordinates[i]; int *proximities = &mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE]; int *proximities = &mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL]; mProximityInfo->calculateNearbyKeyCodes(x, y, primaryKey, proximities); } if (DEBUG_PROXIMITY_CHARS) { for (int i = 0; i < inputLength; ++i) { AKLOGI("---"); for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE; ++j) { int icc = mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE + j]; int icfjc = inputCodes[i * MAX_PROXIMITY_CHARS_SIZE + j]; for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL; ++j) { int icc = mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j]; int icfjc = inputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j]; icc += 0; icfjc += 0; AKLOGI("--- (%d)%c,%c", i, icc, icfjc); AKLOGI("--- A<%d>,B<%d>", icc, icfjc); Loading @@ -54,8 +70,8 @@ void ProximityInfoState::initInputParams(const int32_t* inputCodes, const int in } mInputXCoordinates = xCoordinates; mInputYCoordinates = yCoordinates; mTouchPositionCorrectionEnabled = HAS_TOUCH_POSITION_CORRECTION_DATA && xCoordinates && yCoordinates; mTouchPositionCorrectionEnabled = mHasTouchPositionCorrectionData && xCoordinates && yCoordinates; mInputLength = inputLength; for (int i = 0; i < inputLength; ++i) { mPrimaryInputWord[i] = getPrimaryCharAt(i); Loading @@ -74,17 +90,17 @@ void ProximityInfoState::initInputParams(const int32_t* inputCodes, const int in a += 0; AKLOGI("--- Primary = %c, x = %d, y = %d", primaryKey, x, y); } for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE && proximityChars[j] > 0; ++j) { for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL && proximityChars[j] > 0; ++j) { const int currentChar = proximityChars[j]; const float squaredDistance = hasInputCoordinates() ? calculateNormalizedSquaredDistance( mProximityInfo->getKeyIndex(currentChar), i) : NOT_A_DISTANCE_FLOAT; if (squaredDistance >= 0.0f) { mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] = mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j] = (int) (squaredDistance * NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR); } else { mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] = mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j] = (j == 0) ? EQUIVALENT_CHAR_WITHOUT_DISTANCE_INFO : PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO; } Loading @@ -94,4 +110,30 @@ void ProximityInfoState::initInputParams(const int32_t* inputCodes, const int in } } } 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 == mInputXCoordinates[inputIndex]) { return NOT_A_DISTANCE_FLOAT; } const float squaredDistance = calculateSquaredDistanceFromSweetSpotCenter( keyIndex, inputIndex); const float squaredRadius = square(mProximityInfo->getSweetSpotRadiiAt(keyIndex)); return squaredDistance / squaredRadius; } 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 = (float)mInputXCoordinates[inputIndex]; const float inputY = (float)mInputYCoordinates[inputIndex]; return square(inputX - sweetSpotCenterX) + square(inputY - sweetSpotCenterY); } } // namespace latinime Loading
native/jni/src/correction.cpp +27 −26 Original line number Diff line number Diff line Loading @@ -98,7 +98,7 @@ inline static int getCurrentEditDistance(int *editDistanceTable, const int editD static const char QUOTE = '\''; inline bool Correction::isQuote(const unsigned short c) { const unsigned short userTypedChar = mProximityInfo->getPrimaryCharAt(mInputIndex); const unsigned short userTypedChar = mProximityInfoState.getPrimaryCharAt(mInputIndex); return (c == QUOTE && userTypedChar != QUOTE); } Loading Loading @@ -283,7 +283,7 @@ bool Correction::needsToPrune() const { void Correction::addCharToCurrentWord(const int32_t c) { mWord[mOutputIndex] = c; const unsigned short *primaryInputWord = mProximityInfo->getPrimaryInputWord(); const unsigned short *primaryInputWord = mProximityInfoState.getPrimaryInputWord(); calcEditDistanceOneStep(mEditDistanceTable, primaryInputWord, mInputLength, mWord, mOutputIndex + 1); } Loading Loading @@ -335,19 +335,19 @@ Correction::CorrectionType Correction::processCharAndCalcState( bool incremented = false; if (mLastCharExceeded && mInputIndex == mInputLength - 1) { // TODO: Do not check the proximity if EditDistance exceeds the threshold const ProximityType matchId = mProximityInfo->getMatchedProximityId(mInputIndex, c, true, &proximityIndex); const ProximityType matchId = mProximityInfoState.getMatchedProximityId( mInputIndex, c, true, &proximityIndex); if (isEquivalentChar(matchId)) { mLastCharExceeded = false; --mExcessiveCount; mDistances[mOutputIndex] = mProximityInfo->getNormalizedSquaredDistance(mInputIndex, 0); mProximityInfoState.getNormalizedSquaredDistance(mInputIndex, 0); } else if (matchId == NEAR_PROXIMITY_CHAR) { mLastCharExceeded = false; --mExcessiveCount; ++mProximityCount; mDistances[mOutputIndex] = mProximityInfo->getNormalizedSquaredDistance(mInputIndex, proximityIndex); mDistances[mOutputIndex] = mProximityInfoState.getNormalizedSquaredDistance( mInputIndex, proximityIndex); } if (!isQuote(c)) { incrementInputIndex(); Loading Loading @@ -388,7 +388,8 @@ Correction::CorrectionType Correction::processCharAndCalcState( bool secondTransposing = false; if (mTransposedCount % 2 == 1) { if (isEquivalentChar(mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false))) { if (isEquivalentChar(mProximityInfoState.getMatchedProximityId( mInputIndex - 1, c, false))) { ++mTransposedCount; secondTransposing = true; } else if (mCorrectionStates[mOutputIndex].mExceeding) { Loading Loading @@ -419,7 +420,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( ProximityType matchedProximityCharId = secondTransposing ? EQUIVALENT_CHAR : mProximityInfo->getMatchedProximityId( : mProximityInfoState.getMatchedProximityId( mInputIndex, c, checkProximityChars, &proximityIndex); if (UNRELATED_CHAR == matchedProximityCharId Loading @@ -427,7 +428,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( if (canTryCorrection && mOutputIndex > 0 && mCorrectionStates[mOutputIndex].mProximityMatching && mCorrectionStates[mOutputIndex].mExceeding && isEquivalentChar(mProximityInfo->getMatchedProximityId( && isEquivalentChar(mProximityInfoState.getMatchedProximityId( mInputIndex, mWord[mOutputIndex - 1], false))) { if (DEBUG_CORRECTION && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) Loading @@ -446,7 +447,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( // Here, we are doing something equivalent to matchedProximityCharId, // but we already know that "excessive char correction" just happened // so that we just need to check "mProximityCount == 0". matchedProximityCharId = mProximityInfo->getMatchedProximityId( matchedProximityCharId = mProximityInfoState.getMatchedProximityId( mInputIndex, c, mProximityCount == 0, &proximityIndex); } } Loading @@ -463,10 +464,10 @@ Correction::CorrectionType Correction::processCharAndCalcState( if (mInputIndex < mInputLength - 1 && mOutputIndex > 0 && mTransposedCount > 0 && !mCorrectionStates[mOutputIndex].mTransposing && mCorrectionStates[mOutputIndex - 1].mTransposing && isEquivalentChar(mProximityInfo->getMatchedProximityId( && isEquivalentChar(mProximityInfoState.getMatchedProximityId( mInputIndex, mWord[mOutputIndex - 1], false)) && isEquivalentChar( mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false))) { mProximityInfoState.getMatchedProximityId(mInputIndex + 1, c, false))) { // Conversion t->e // Example: // occaisional -> occa sional Loading @@ -478,7 +479,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( && !mCorrectionStates[mOutputIndex].mTransposing && mCorrectionStates[mOutputIndex - 1].mTransposing && isEquivalentChar( mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false))) { mProximityInfoState.getMatchedProximityId(mInputIndex - 1, c, false))) { // Conversion t->s // Example: // chcolate -> chocolate Loading @@ -490,7 +491,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( && mCorrectionStates[mOutputIndex].mProximityMatching && mCorrectionStates[mOutputIndex].mSkipping && isEquivalentChar( mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false))) { mProximityInfoState.getMatchedProximityId(mInputIndex - 1, c, false))) { // Conversion p->s // Note: This logic tries saving cases like contrst --> contrast -- "a" is one of // proximity chars of "s", but it should rather be handled as a skipped char. Loading @@ -502,7 +503,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( && mCorrectionStates[mOutputIndex].mSkipping && mCorrectionStates[mOutputIndex].mAdditionalProximityMatching && isProximityCharOrEquivalentChar( mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false))) { mProximityInfoState.getMatchedProximityId(mInputIndex + 1, c, false))) { // Conversion s->a incrementInputIndex(); --mSkippedCount; Loading @@ -511,7 +512,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( mDistances[mOutputIndex] = ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO; } else if ((mExceeding || mTransposing) && mInputIndex - 1 < mInputLength && isEquivalentChar( mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false))) { mProximityInfoState.getMatchedProximityId(mInputIndex + 1, c, false))) { // 1.2. Excessive or transpose correction if (mTransposing) { ++mTransposedCount; Loading Loading @@ -573,12 +574,12 @@ Correction::CorrectionType Correction::processCharAndCalcState( } else if (isEquivalentChar(matchedProximityCharId)) { mMatching = true; ++mEquivalentCharCount; mDistances[mOutputIndex] = mProximityInfo->getNormalizedSquaredDistance(mInputIndex, 0); mDistances[mOutputIndex] = mProximityInfoState.getNormalizedSquaredDistance(mInputIndex, 0); } else if (NEAR_PROXIMITY_CHAR == matchedProximityCharId) { mProximityMatching = true; ++mProximityCount; mDistances[mOutputIndex] = mProximityInfo->getNormalizedSquaredDistance(mInputIndex, proximityIndex); mProximityInfoState.getNormalizedSquaredDistance(mInputIndex, proximityIndex); if (DEBUG_CORRECTION && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 Loading Loading @@ -662,7 +663,7 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex const int excessivePos = correction->getExcessivePos(); const int typedLetterMultiplier = correction->TYPED_LETTER_MULTIPLIER; const int fullWordMultiplier = correction->FULL_WORD_MULTIPLIER; const ProximityInfo *proximityInfo = correction->mProximityInfo; const ProximityInfoState *proximityInfoState = &correction->mProximityInfoState; const int skippedCount = correction->mSkippedCount; const int transposedCount = correction->mTransposedCount / 2; const int excessiveCount = correction->mExcessiveCount + correction->mTransposedCount % 2; Loading @@ -685,7 +686,7 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex const bool skipped = skippedCount > 0; const int quoteDiffCount = max(0, getQuoteCount(word, outputLength) - getQuoteCount(proximityInfo->getPrimaryInputWord(), inputLength)); - getQuoteCount(proximityInfoState->getPrimaryInputWord(), inputLength)); // TODO: Calculate edit distance for transposed and excessive int ed = 0; Loading Loading @@ -737,7 +738,7 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex multiplyIntCapped(matchWeight, &finalFreq); } if (proximityInfo->getMatchedProximityId(0, word[0], true) == UNRELATED_CHAR) { if (proximityInfoState->getMatchedProximityId(0, word[0], true) == UNRELATED_CHAR) { multiplyRate(FIRST_CHAR_DIFFERENT_DEMOTION_RATE, &finalFreq); } Loading @@ -763,7 +764,7 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex // Demotion for a word with excessive character if (excessiveCount > 0) { multiplyRate(WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE, &finalFreq); if (!lastCharExceeded && !proximityInfo->existsAdjacentProximityChars(excessivePos)) { if (!lastCharExceeded && !proximityInfoState->existsAdjacentProximityChars(excessivePos)) { if (DEBUG_DICT_FULL) { AKLOGI("Double excessive demotion"); } Loading @@ -774,7 +775,8 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex } const bool performTouchPositionCorrection = CALIBRATE_SCORE_BY_TOUCH_COORDINATES && proximityInfo->touchPositionCorrectionEnabled() CALIBRATE_SCORE_BY_TOUCH_COORDINATES && proximityInfoState->touchPositionCorrectionEnabled() && skippedCount == 0 && excessiveCount == 0 && transposedCount == 0; // Score calibration by touch coordinates is being done only for pure-fat finger typing error // cases. Loading Loading @@ -1145,5 +1147,4 @@ float Correction::RankingAlgorithm::calcNormalizedScore(const unsigned short* be const float weight = 1.0 - (float) distance / afterLength; return (score / maxScore) * weight; } } // namespace latinime
native/jni/src/correction.h +18 −2 Original line number Diff line number Diff line Loading @@ -19,9 +19,10 @@ #include <assert.h> #include <stdint.h> #include "correction_state.h" #include "correction_state.h" #include "defines.h" #include "proximity_info_state.h" namespace latinime { Loading Loading @@ -178,6 +179,21 @@ class Correction { static const int FULL_WORD_MULTIPLIER = 2; }; // proximity info state void initInputParams(const ProximityInfo *proximityInfo, const int32_t *inputCodes, const int inputLength, const int *xCoordinates, const int *yCoordinates) { mProximityInfoState.initInputParams( proximityInfo, inputCodes, inputLength, xCoordinates, yCoordinates); } const unsigned short* getPrimaryInputWord() const { return mProximityInfoState.getPrimaryInputWord(); } unsigned short getPrimaryCharAt(const int index) const { return mProximityInfoState.getPrimaryCharAt(index); } private: inline void incrementInputIndex(); inline void incrementOutputIndex(); Loading Loading @@ -240,7 +256,7 @@ class Correction { bool mExceeding; bool mTransposing; bool mSkipping; ProximityInfoState mProximityInfoState; }; } // namespace latinime #endif // LATINIME_CORRECTION_H
native/jni/src/proximity_info.cpp +0 −53 Original line number Diff line number Diff line Loading @@ -73,9 +73,6 @@ ProximityInfo::ProximityInfo(const std::string localeStr, const int maxProximity copyOrFillZero(mSweetSpotRadii, sweetSpotRadii, KEY_COUNT * sizeof(mSweetSpotRadii[0])); initializeCodeToKeyIndex(); mProximityInfoState = new ProximityInfoState(this, MAX_PROXIMITY_CHARS_SIZE, HAS_TOUCH_POSITION_CORRECTION_DATA, MOST_COMMON_KEY_WIDTH_SQUARE, mLocaleStr, KEY_COUNT, CELL_HEIGHT, CELL_WIDTH, GRID_WIDTH, GRID_HEIGHT); } // Build the reversed look up table from the char code to the index in mKeyXCoordinates, Loading @@ -92,7 +89,6 @@ void ProximityInfo::initializeCodeToKeyIndex() { ProximityInfo::~ProximityInfo() { delete[] mProximityCharsArray; delete mProximityInfoState; } inline int ProximityInfo::getStartIndexFromCoordinates(const int x, const int y) const { Loading Loading @@ -203,12 +199,6 @@ void ProximityInfo::calculateNearbyKeyCodes( } } // TODO: remove void ProximityInfo::initInputParams(const int32_t *inputCodes, const int inputLength, const int *xCoordinates, const int *yCoordinates) { mProximityInfoState->initInputParams(inputCodes, inputLength, xCoordinates, yCoordinates); } int ProximityInfo::getKeyIndex(const int c) const { if (KEY_COUNT == 0) { // We do not have the coordinate data Loading @@ -220,47 +210,4 @@ int ProximityInfo::getKeyIndex(const int c) const { } return mCodeToKeyIndex[baseLowerC]; } // TODO: remove inline const int* ProximityInfo::getProximityCharsAt(const int index) const { return mProximityInfoState->getProximityCharsAt(index); } // TODO: remove unsigned short ProximityInfo::getPrimaryCharAt(const int index) const { return mProximityInfoState->getPrimaryCharAt(index); } // TODO: remove bool ProximityInfo::existsCharInProximityAt(const int index, const int c) const { return mProximityInfoState->existsCharInProximityAt(index, c); } // TODO: remove bool ProximityInfo::existsAdjacentProximityChars(const int index) const { return mProximityInfoState->existsAdjacentProximityChars(index); } // TODO: remove ProximityType ProximityInfo::getMatchedProximityId(const int index, const unsigned short c, const bool checkProximityChars, int *proximityIndex) const { return mProximityInfoState->getMatchedProximityId( index, c, checkProximityChars, proximityIndex); } // TODO: remove int ProximityInfo::getNormalizedSquaredDistance( const int inputIndex, const int proximityIndex) const { return mProximityInfoState->getNormalizedSquaredDistance(inputIndex, proximityIndex); } // TODO: remove const unsigned short* ProximityInfo::getPrimaryInputWord() const { return mProximityInfoState->getPrimaryInputWord(); } // TODO: remove bool ProximityInfo::touchPositionCorrectionEnabled() const { return mProximityInfoState->touchPositionCorrectionEnabled(); } } // namespace latinime
native/jni/src/proximity_info.h +31 −18 Original line number Diff line number Diff line Loading @@ -25,11 +25,9 @@ namespace latinime { class Correction; class ProximityInfoState; class ProximityInfo { public: ProximityInfo(const std::string localeStr, const int maxProximityCharsSize, const int keyboardWidth, const int keyboardHeight, const int gridWidth, const int gridHeight, const int mostCommonkeyWidth, Loading Loading @@ -68,21 +66,37 @@ class ProximityInfo { void calculateNearbyKeyCodes( const int x, const int y, const int32_t primaryKey, int *inputCodes) const; //////////////////////////////////// // Access to proximity info state // // TODO: remove // //////////////////////////////////// void initInputParams(const int32_t *inputCodes, const int inputLength, const int *xCoordinates, const int *yCoordinates); const int* getProximityCharsAt(const int index) const; unsigned short getPrimaryCharAt(const int index) const; bool existsCharInProximityAt(const int index, const int c) const; bool existsAdjacentProximityChars(const int index) const; ProximityType getMatchedProximityId(const int index, const unsigned short c, const bool checkProximityChars, int *proximityIndex = 0) const; const unsigned short* getPrimaryInputWord() const; bool touchPositionCorrectionEnabled() const; //////////////////////////////////// bool hasTouchPositionCorrectionData() const { return HAS_TOUCH_POSITION_CORRECTION_DATA; } int getMostCommonKeyWidthSquare() const { return MOST_COMMON_KEY_WIDTH_SQUARE; } std::string getLocaleStr() const { return mLocaleStr; } int getKeyCount() const { return KEY_COUNT; } int getCellHeight() const { return CELL_HEIGHT; } int getCellWidth() const { return CELL_WIDTH; } int getGridWidth() const { return GRID_WIDTH; } int getGridHeight() const { return GRID_HEIGHT; } private: // The max number of the keys in one keyboard layout Loading Loading @@ -121,7 +135,6 @@ class ProximityInfo { float mSweetSpotRadii[MAX_KEY_COUNT_IN_A_KEYBOARD]; int mCodeToKeyIndex[MAX_CHAR_CODE + 1]; // TODO: move to correction.h ProximityInfoState *mProximityInfoState; }; } // namespace latinime Loading
native/jni/src/proximity_info_state.cpp +53 −11 Original line number Diff line number Diff line Loading @@ -27,25 +27,41 @@ #include "proximity_info_state.h" namespace latinime { void ProximityInfoState::initInputParams(const int32_t* inputCodes, const int inputLength, void ProximityInfoState::initInputParams( const ProximityInfo* proximityInfo, const int32_t* inputCodes, const int inputLength, const int* xCoordinates, const int* yCoordinates) { mProximityInfo = proximityInfo; mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData(); mMostCommonKeyWidthSquare = proximityInfo->getMostCommonKeyWidthSquare(); mLocaleStr = proximityInfo->getLocaleStr(); mKeyCount = proximityInfo->getKeyCount(); mCellHeight = proximityInfo->getCellHeight(); mCellWidth = proximityInfo->getCellWidth(); mGridHeight = proximityInfo->getGridWidth(); mGridWidth = proximityInfo->getGridHeight(); const int normalizedSquaredDistancesLength = MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH_INTERNAL; for (int i = 0; i < normalizedSquaredDistancesLength; ++i) { mNormalizedSquaredDistances[i] = NOT_A_DISTANCE; } memset(mInputCodes, 0, MAX_WORD_LENGTH_INTERNAL * MAX_PROXIMITY_CHARS_SIZE * sizeof(mInputCodes[0])); MAX_WORD_LENGTH_INTERNAL * MAX_PROXIMITY_CHARS_SIZE_INTERNAL * sizeof(mInputCodes[0])); for (int i = 0; i < inputLength; ++i) { const int32_t primaryKey = inputCodes[i]; const int x = xCoordinates[i]; const int y = yCoordinates[i]; int *proximities = &mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE]; int *proximities = &mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL]; mProximityInfo->calculateNearbyKeyCodes(x, y, primaryKey, proximities); } if (DEBUG_PROXIMITY_CHARS) { for (int i = 0; i < inputLength; ++i) { AKLOGI("---"); for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE; ++j) { int icc = mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE + j]; int icfjc = inputCodes[i * MAX_PROXIMITY_CHARS_SIZE + j]; for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL; ++j) { int icc = mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j]; int icfjc = inputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j]; icc += 0; icfjc += 0; AKLOGI("--- (%d)%c,%c", i, icc, icfjc); AKLOGI("--- A<%d>,B<%d>", icc, icfjc); Loading @@ -54,8 +70,8 @@ void ProximityInfoState::initInputParams(const int32_t* inputCodes, const int in } mInputXCoordinates = xCoordinates; mInputYCoordinates = yCoordinates; mTouchPositionCorrectionEnabled = HAS_TOUCH_POSITION_CORRECTION_DATA && xCoordinates && yCoordinates; mTouchPositionCorrectionEnabled = mHasTouchPositionCorrectionData && xCoordinates && yCoordinates; mInputLength = inputLength; for (int i = 0; i < inputLength; ++i) { mPrimaryInputWord[i] = getPrimaryCharAt(i); Loading @@ -74,17 +90,17 @@ void ProximityInfoState::initInputParams(const int32_t* inputCodes, const int in a += 0; AKLOGI("--- Primary = %c, x = %d, y = %d", primaryKey, x, y); } for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE && proximityChars[j] > 0; ++j) { for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL && proximityChars[j] > 0; ++j) { const int currentChar = proximityChars[j]; const float squaredDistance = hasInputCoordinates() ? calculateNormalizedSquaredDistance( mProximityInfo->getKeyIndex(currentChar), i) : NOT_A_DISTANCE_FLOAT; if (squaredDistance >= 0.0f) { mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] = mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j] = (int) (squaredDistance * NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR); } else { mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] = mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j] = (j == 0) ? EQUIVALENT_CHAR_WITHOUT_DISTANCE_INFO : PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO; } Loading @@ -94,4 +110,30 @@ void ProximityInfoState::initInputParams(const int32_t* inputCodes, const int in } } } 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 == mInputXCoordinates[inputIndex]) { return NOT_A_DISTANCE_FLOAT; } const float squaredDistance = calculateSquaredDistanceFromSweetSpotCenter( keyIndex, inputIndex); const float squaredRadius = square(mProximityInfo->getSweetSpotRadiiAt(keyIndex)); return squaredDistance / squaredRadius; } 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 = (float)mInputXCoordinates[inputIndex]; const float inputY = (float)mInputYCoordinates[inputIndex]; return square(inputX - sweetSpotCenterX) + square(inputY - sweetSpotCenterY); } } // namespace latinime