am 687a2447: Step 38-A Cleanup touch path

* commit '687a244703a02323ebd64433cbaead5def499861':
  Step 38-A Cleanup touch path
main
Satoshi Kataoka 2012-08-23 20:07:51 -07:00 committed by Android Git Automerger
commit dc8b73a8d1
8 changed files with 252 additions and 140 deletions

View File

@ -61,19 +61,19 @@ inline static void dumpEditDistance10ForDebug(int *editDistanceTable,
} }
inline static void calcEditDistanceOneStep(int *editDistanceTable, const unsigned short *input, inline static void calcEditDistanceOneStep(int *editDistanceTable, const unsigned short *input,
const int inputLength, const unsigned short *output, const int outputLength) { const int inputSize, const unsigned short *output, const int outputLength) {
// TODO: Make sure that editDistance[0 ~ MAX_WORD_LENGTH_INTERNAL] is not touched. // TODO: Make sure that editDistance[0 ~ MAX_WORD_LENGTH_INTERNAL] is not touched.
// Let dp[i][j] be editDistanceTable[i * (inputLength + 1) + j]. // Let dp[i][j] be editDistanceTable[i * (inputSize + 1) + j].
// Assuming that dp[0][0] ... dp[outputLength - 1][inputLength] are already calculated, // Assuming that dp[0][0] ... dp[outputLength - 1][inputSize] are already calculated,
// and calculate dp[ouputLength][0] ... dp[outputLength][inputLength]. // and calculate dp[ouputLength][0] ... dp[outputLength][inputSize].
int *const current = editDistanceTable + outputLength * (inputLength + 1); int *const current = editDistanceTable + outputLength * (inputSize + 1);
const int *const prev = editDistanceTable + (outputLength - 1) * (inputLength + 1); const int *const prev = editDistanceTable + (outputLength - 1) * (inputSize + 1);
const int *const prevprev = const int *const prevprev =
outputLength >= 2 ? editDistanceTable + (outputLength - 2) * (inputLength + 1) : 0; outputLength >= 2 ? editDistanceTable + (outputLength - 2) * (inputSize + 1) : 0;
current[0] = outputLength; current[0] = outputLength;
const uint32_t co = toBaseLowerCase(output[outputLength - 1]); const uint32_t co = toBaseLowerCase(output[outputLength - 1]);
const uint32_t prevCO = outputLength >= 2 ? toBaseLowerCase(output[outputLength - 2]) : 0; const uint32_t prevCO = outputLength >= 2 ? toBaseLowerCase(output[outputLength - 2]) : 0;
for (int i = 1; i <= inputLength; ++i) { for (int i = 1; i <= inputSize; ++i) {
const uint32_t ci = toBaseLowerCase(input[i - 1]); const uint32_t ci = toBaseLowerCase(input[i - 1]);
const uint16_t cost = (ci == co) ? 0 : 1; const uint16_t cost = (ci == co) ? 0 : 1;
current[i] = min(current[i - 1] + 1, min(prev[i] + 1, prev[i - 1] + cost)); current[i] = min(current[i - 1] + 1, min(prev[i] + 1, prev[i - 1] + cost));
@ -84,11 +84,11 @@ inline static void calcEditDistanceOneStep(int *editDistanceTable, const unsigne
} }
inline static int getCurrentEditDistance(int *editDistanceTable, const int editDistanceTableWidth, inline static int getCurrentEditDistance(int *editDistanceTable, const int editDistanceTableWidth,
const int outputLength, const int inputLength) { const int outputLength, const int inputSize) {
if (DEBUG_EDIT_DISTANCE) { if (DEBUG_EDIT_DISTANCE) {
AKLOGI("getCurrentEditDistance %d, %d", inputLength, outputLength); AKLOGI("getCurrentEditDistance %d, %d", inputSize, outputLength);
} }
return editDistanceTable[(editDistanceTableWidth + 1) * (outputLength) + inputLength]; return editDistanceTable[(editDistanceTableWidth + 1) * (outputLength) + inputSize];
} }
////////////////////// //////////////////////
@ -109,12 +109,12 @@ void Correction::resetCorrection() {
mTotalTraverseCount = 0; mTotalTraverseCount = 0;
} }
void Correction::initCorrection(const ProximityInfo *pi, const int inputLength, void Correction::initCorrection(const ProximityInfo *pi, const int inputSize,
const int maxDepth) { const int maxDepth) {
mProximityInfo = pi; mProximityInfo = pi;
mInputLength = inputLength; mInputSize = inputSize;
mMaxDepth = maxDepth; mMaxDepth = maxDepth;
mMaxEditDistance = mInputLength < 5 ? 2 : mInputLength / 2; mMaxEditDistance = mInputSize < 5 ? 2 : mInputSize / 2;
// TODO: This is not supposed to be required. Check what's going wrong with // TODO: This is not supposed to be required. Check what's going wrong with
// editDistance[0 ~ MAX_WORD_LENGTH_INTERNAL] // editDistance[0 ~ MAX_WORD_LENGTH_INTERNAL]
initEditDistance(mEditDistanceTable); initEditDistance(mEditDistanceTable);
@ -168,22 +168,22 @@ int Correction::getFreqForSplitMultipleWords(const int *freqArray, const int *wo
} }
int Correction::getFinalProbability(const int probability, unsigned short **word, int *wordLength) { int Correction::getFinalProbability(const int probability, unsigned short **word, int *wordLength) {
return getFinalProbabilityInternal(probability, word, wordLength, mInputLength); return getFinalProbabilityInternal(probability, word, wordLength, mInputSize);
} }
int Correction::getFinalProbabilityForSubQueue(const int probability, unsigned short **word, int Correction::getFinalProbabilityForSubQueue(const int probability, unsigned short **word,
int *wordLength, const int inputLength) { int *wordLength, const int inputSize) {
return getFinalProbabilityInternal(probability, word, wordLength, inputLength); return getFinalProbabilityInternal(probability, word, wordLength, inputSize);
} }
int Correction::getFinalProbabilityInternal(const int probability, unsigned short **word, int Correction::getFinalProbabilityInternal(const int probability, unsigned short **word,
int *wordLength, const int inputLength) { int *wordLength, const int inputSize) {
const int outputIndex = mTerminalOutputIndex; const int outputIndex = mTerminalOutputIndex;
const int inputIndex = mTerminalInputIndex; const int inputIndex = mTerminalInputIndex;
*wordLength = outputIndex + 1; *wordLength = outputIndex + 1;
*word = mWord; *word = mWord;
int finalProbability= Correction::RankingAlgorithm::calculateFinalProbability( int finalProbability= Correction::RankingAlgorithm::calculateFinalProbability(
inputIndex, outputIndex, probability, mEditDistanceTable, this, inputLength); inputIndex, outputIndex, probability, mEditDistanceTable, this, inputSize);
return finalProbability; return finalProbability;
} }
@ -270,13 +270,13 @@ bool Correction::needsToPrune() const {
// TODO: use edit distance here // TODO: use edit distance here
return mOutputIndex - 1 >= mMaxDepth || mProximityCount > mMaxEditDistance return mOutputIndex - 1 >= mMaxDepth || mProximityCount > mMaxEditDistance
// Allow one char longer word for missing character // Allow one char longer word for missing character
|| (!mDoAutoCompletion && (mOutputIndex > mInputLength)); || (!mDoAutoCompletion && (mOutputIndex > mInputSize));
} }
void Correction::addCharToCurrentWord(const int32_t c) { void Correction::addCharToCurrentWord(const int32_t c) {
mWord[mOutputIndex] = c; mWord[mOutputIndex] = c;
const unsigned short *primaryInputWord = mProximityInfoState.getPrimaryInputWord(); const unsigned short *primaryInputWord = mProximityInfoState.getPrimaryInputWord();
calcEditDistanceOneStep(mEditDistanceTable, primaryInputWord, mInputLength, calcEditDistanceOneStep(mEditDistanceTable, primaryInputWord, mInputSize,
mWord, mOutputIndex + 1); mWord, mOutputIndex + 1);
} }
@ -325,7 +325,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
// Skip checking this node // Skip checking this node
if (mNeedsToTraverseAllNodes || isSingleQuote(c)) { if (mNeedsToTraverseAllNodes || isSingleQuote(c)) {
bool incremented = false; bool incremented = false;
if (mLastCharExceeded && mInputIndex == mInputLength - 1) { if (mLastCharExceeded && mInputIndex == mInputSize - 1) {
// TODO: Do not check the proximity if EditDistance exceeds the threshold // TODO: Do not check the proximity if EditDistance exceeds the threshold
const ProximityType matchId = mProximityInfoState.getMatchedProximityId( const ProximityType matchId = mProximityInfoState.getMatchedProximityId(
mInputIndex, c, true, &proximityIndex); mInputIndex, c, true, &proximityIndex);
@ -354,7 +354,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
if (mExcessiveCount == 0 && mExcessivePos < mOutputIndex) { if (mExcessiveCount == 0 && mExcessivePos < mOutputIndex) {
mExcessivePos = mOutputIndex; mExcessivePos = mOutputIndex;
} }
if (mExcessivePos < mInputLength - 1) { if (mExcessivePos < mInputSize - 1) {
mExceeding = mExcessivePos == mInputIndex && canTryCorrection; mExceeding = mExcessivePos == mInputIndex && canTryCorrection;
} }
} }
@ -373,7 +373,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
if (mTransposedCount == 0 && mTransposedPos < mOutputIndex) { if (mTransposedCount == 0 && mTransposedPos < mOutputIndex) {
mTransposedPos = mOutputIndex; mTransposedPos = mOutputIndex;
} }
if (mTransposedPos < mInputLength - 1) { if (mTransposedPos < mInputSize - 1) {
mTransposing = mInputIndex == mTransposedPos && canTryCorrection; mTransposing = mInputIndex == mTransposedPos && canTryCorrection;
} }
} }
@ -392,7 +392,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
} else { } else {
--mTransposedCount; --mTransposedCount;
if (DEBUG_CORRECTION if (DEBUG_CORRECTION
&& (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize)
&& (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0
|| MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) {
DUMP_WORD(mWord, mOutputIndex); DUMP_WORD(mWord, mOutputIndex);
@ -423,7 +423,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
&& isEquivalentChar(mProximityInfoState.getMatchedProximityId( && isEquivalentChar(mProximityInfoState.getMatchedProximityId(
mInputIndex, mWord[mOutputIndex - 1], false))) { mInputIndex, mWord[mOutputIndex - 1], false))) {
if (DEBUG_CORRECTION if (DEBUG_CORRECTION
&& (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize)
&& (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0
|| MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) {
AKLOGI("CONVERSION p->e %c", mWord[mOutputIndex - 1]); AKLOGI("CONVERSION p->e %c", mWord[mOutputIndex - 1]);
@ -453,7 +453,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
// As the current char turned out to be an unrelated char, // As the current char turned out to be an unrelated char,
// we will try other correction-types. Please note that mCorrectionStates[mOutputIndex] // we will try other correction-types. Please note that mCorrectionStates[mOutputIndex]
// here refers to the previous state. // here refers to the previous state.
if (mInputIndex < mInputLength - 1 && mOutputIndex > 0 && mTransposedCount > 0 if (mInputIndex < mInputSize - 1 && mOutputIndex > 0 && mTransposedCount > 0
&& !mCorrectionStates[mOutputIndex].mTransposing && !mCorrectionStates[mOutputIndex].mTransposing
&& mCorrectionStates[mOutputIndex - 1].mTransposing && mCorrectionStates[mOutputIndex - 1].mTransposing
&& isEquivalentChar(mProximityInfoState.getMatchedProximityId( && isEquivalentChar(mProximityInfoState.getMatchedProximityId(
@ -490,7 +490,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
++mSkippedCount; ++mSkippedCount;
--mProximityCount; --mProximityCount;
return processSkipChar(c, isTerminal, false); return processSkipChar(c, isTerminal, false);
} else if (mInputIndex - 1 < mInputLength } else if (mInputIndex - 1 < mInputSize
&& mSkippedCount > 0 && mSkippedCount > 0
&& mCorrectionStates[mOutputIndex].mSkipping && mCorrectionStates[mOutputIndex].mSkipping
&& mCorrectionStates[mOutputIndex].mAdditionalProximityMatching && mCorrectionStates[mOutputIndex].mAdditionalProximityMatching
@ -502,7 +502,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
mProximityMatching = true; mProximityMatching = true;
++mProximityCount; ++mProximityCount;
mDistances[mOutputIndex] = ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO; mDistances[mOutputIndex] = ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO;
} else if ((mExceeding || mTransposing) && mInputIndex - 1 < mInputLength } else if ((mExceeding || mTransposing) && mInputIndex - 1 < mInputSize
&& isEquivalentChar( && isEquivalentChar(
mProximityInfoState.getMatchedProximityId(mInputIndex + 1, c, false))) { mProximityInfoState.getMatchedProximityId(mInputIndex + 1, c, false))) {
// 1.2. Excessive or transpose correction // 1.2. Excessive or transpose correction
@ -513,7 +513,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
incrementInputIndex(); incrementInputIndex();
} }
if (DEBUG_CORRECTION if (DEBUG_CORRECTION
&& (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize)
&& (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0
|| MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) {
DUMP_WORD(mWord, mOutputIndex); DUMP_WORD(mWord, mOutputIndex);
@ -529,7 +529,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
// 3. Skip correction // 3. Skip correction
++mSkippedCount; ++mSkippedCount;
if (DEBUG_CORRECTION if (DEBUG_CORRECTION
&& (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize)
&& (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0
|| MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) {
AKLOGI("SKIP: %d, %d, %d, %d, %c", mProximityCount, mSkippedCount, AKLOGI("SKIP: %d, %d, %d, %d, %c", mProximityCount, mSkippedCount,
@ -542,7 +542,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
++mProximityCount; ++mProximityCount;
mDistances[mOutputIndex] = ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO; mDistances[mOutputIndex] = ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO;
if (DEBUG_CORRECTION if (DEBUG_CORRECTION
&& (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize)
&& (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0
|| MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) {
AKLOGI("ADDITIONALPROX: %d, %d, %d, %d, %c", mProximityCount, mSkippedCount, AKLOGI("ADDITIONALPROX: %d, %d, %d, %d, %c", mProximityCount, mSkippedCount,
@ -550,7 +550,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
} }
} else { } else {
if (DEBUG_CORRECTION if (DEBUG_CORRECTION
&& (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize)
&& (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0
|| MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) {
DUMP_WORD(mWord, mOutputIndex); DUMP_WORD(mWord, mOutputIndex);
@ -560,7 +560,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
return processUnrelatedCorrectionType(); return processUnrelatedCorrectionType();
} }
} else if (secondTransposing) { } else if (secondTransposing) {
// If inputIndex is greater than mInputLength, that means there is no // If inputIndex is greater than mInputSize, that means there is no
// proximity chars. So, we don't need to check proximity. // proximity chars. So, we don't need to check proximity.
mMatching = true; mMatching = true;
} else if (isEquivalentChar(matchedProximityCharId)) { } else if (isEquivalentChar(matchedProximityCharId)) {
@ -573,7 +573,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
mDistances[mOutputIndex] = mDistances[mOutputIndex] =
mProximityInfoState.getNormalizedSquaredDistance(mInputIndex, proximityIndex); mProximityInfoState.getNormalizedSquaredDistance(mInputIndex, proximityIndex);
if (DEBUG_CORRECTION if (DEBUG_CORRECTION
&& (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize)
&& (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0
|| MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) {
AKLOGI("PROX: %d, %d, %d, %d, %c", mProximityCount, mSkippedCount, AKLOGI("PROX: %d, %d, %d, %d, %c", mProximityCount, mSkippedCount,
@ -585,8 +585,8 @@ Correction::CorrectionType Correction::processCharAndCalcState(
// 4. Last char excessive correction // 4. Last char excessive correction
mLastCharExceeded = mExcessiveCount == 0 && mSkippedCount == 0 && mTransposedCount == 0 mLastCharExceeded = mExcessiveCount == 0 && mSkippedCount == 0 && mTransposedCount == 0
&& mProximityCount == 0 && (mInputIndex == mInputLength - 2); && mProximityCount == 0 && (mInputIndex == mInputSize - 2);
const bool isSameAsUserTypedLength = (mInputLength == mInputIndex + 1) || mLastCharExceeded; const bool isSameAsUserTypedLength = (mInputSize == mInputIndex + 1) || mLastCharExceeded;
if (mLastCharExceeded) { if (mLastCharExceeded) {
++mExcessiveCount; ++mExcessiveCount;
} }
@ -597,7 +597,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
} }
const bool needsToTryOnTerminalForTheLastPossibleExcessiveChar = const bool needsToTryOnTerminalForTheLastPossibleExcessiveChar =
mExceeding && mInputIndex == mInputLength - 2; mExceeding && mInputIndex == mInputSize - 2;
// Finally, we are ready to go to the next character, the next "virtual node". // Finally, we are ready to go to the next character, the next "virtual node".
// We should advance the input index. // We should advance the input index.
@ -613,7 +613,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
mTerminalInputIndex = mInputIndex - 1; mTerminalInputIndex = mInputIndex - 1;
mTerminalOutputIndex = mOutputIndex - 1; mTerminalOutputIndex = mOutputIndex - 1;
if (DEBUG_CORRECTION if (DEBUG_CORRECTION
&& (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize)
&& (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) {
DUMP_WORD(mWord, mOutputIndex); DUMP_WORD(mWord, mOutputIndex);
AKLOGI("ONTERMINAL(1): %d, %d, %d, %d, %c", mProximityCount, mSkippedCount, AKLOGI("ONTERMINAL(1): %d, %d, %d, %d, %c", mProximityCount, mSkippedCount,
@ -651,7 +651,7 @@ inline static bool isUpperCase(unsigned short c) {
/* static */ /* static */
int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex, int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex,
const int outputIndex, const int freq, int *editDistanceTable, const Correction *correction, const int outputIndex, const int freq, int *editDistanceTable, const Correction *correction,
const int inputLength) { const int inputSize) {
const int excessivePos = correction->getExcessivePos(); const int excessivePos = correction->getExcessivePos();
const int typedLetterMultiplier = correction->TYPED_LETTER_MULTIPLIER; const int typedLetterMultiplier = correction->TYPED_LETTER_MULTIPLIER;
const int fullWordMultiplier = correction->FULL_WORD_MULTIPLIER; const int fullWordMultiplier = correction->FULL_WORD_MULTIPLIER;
@ -663,55 +663,55 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex
const bool lastCharExceeded = correction->mLastCharExceeded; const bool lastCharExceeded = correction->mLastCharExceeded;
const bool useFullEditDistance = correction->mUseFullEditDistance; const bool useFullEditDistance = correction->mUseFullEditDistance;
const int outputLength = outputIndex + 1; const int outputLength = outputIndex + 1;
if (skippedCount >= inputLength || inputLength == 0) { if (skippedCount >= inputSize || inputSize == 0) {
return -1; return -1;
} }
// TODO: find more robust way // TODO: find more robust way
bool sameLength = lastCharExceeded ? (inputLength == inputIndex + 2) bool sameLength = lastCharExceeded ? (inputSize == inputIndex + 2)
: (inputLength == inputIndex + 1); : (inputSize == inputIndex + 1);
// TODO: use mExcessiveCount // TODO: use mExcessiveCount
const int matchCount = inputLength - correction->mProximityCount - excessiveCount; const int matchCount = inputSize - correction->mProximityCount - excessiveCount;
const unsigned short *word = correction->mWord; const unsigned short *word = correction->mWord;
const bool skipped = skippedCount > 0; const bool skipped = skippedCount > 0;
const int quoteDiffCount = max(0, getQuoteCount(word, outputLength) const int quoteDiffCount = max(0, getQuoteCount(word, outputLength)
- getQuoteCount(proximityInfoState->getPrimaryInputWord(), inputLength)); - getQuoteCount(proximityInfoState->getPrimaryInputWord(), inputSize));
// TODO: Calculate edit distance for transposed and excessive // TODO: Calculate edit distance for transposed and excessive
int ed = 0; int ed = 0;
if (DEBUG_DICT_FULL) { if (DEBUG_DICT_FULL) {
dumpEditDistance10ForDebug(editDistanceTable, correction->mInputLength, outputLength); dumpEditDistance10ForDebug(editDistanceTable, correction->mInputSize, outputLength);
} }
int adjustedProximityMatchedCount = proximityMatchedCount; int adjustedProximityMatchedCount = proximityMatchedCount;
int finalFreq = freq; int finalFreq = freq;
if (DEBUG_CORRECTION_FREQ if (DEBUG_CORRECTION_FREQ
&& (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == inputLength)) { && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == inputSize)) {
AKLOGI("FinalFreq0: %d", finalFreq); AKLOGI("FinalFreq0: %d", finalFreq);
} }
// TODO: Optimize this. // TODO: Optimize this.
if (transposedCount > 0 || proximityMatchedCount > 0 || skipped || excessiveCount > 0) { if (transposedCount > 0 || proximityMatchedCount > 0 || skipped || excessiveCount > 0) {
ed = getCurrentEditDistance(editDistanceTable, correction->mInputLength, outputLength, ed = getCurrentEditDistance(editDistanceTable, correction->mInputSize, outputLength,
inputLength) - transposedCount; inputSize) - transposedCount;
const int matchWeight = powerIntCapped(typedLetterMultiplier, const int matchWeight = powerIntCapped(typedLetterMultiplier,
max(inputLength, outputLength) - ed); max(inputSize, outputLength) - ed);
multiplyIntCapped(matchWeight, &finalFreq); multiplyIntCapped(matchWeight, &finalFreq);
// TODO: Demote further if there are two or more excessive chars with longer user input? // TODO: Demote further if there are two or more excessive chars with longer user input?
if (inputLength > outputLength) { if (inputSize > outputLength) {
multiplyRate(INPUT_EXCEEDS_OUTPUT_DEMOTION_RATE, &finalFreq); multiplyRate(INPUT_EXCEEDS_OUTPUT_DEMOTION_RATE, &finalFreq);
} }
ed = max(0, ed - quoteDiffCount); ed = max(0, ed - quoteDiffCount);
adjustedProximityMatchedCount = min(max(0, ed - (outputLength - inputLength)), adjustedProximityMatchedCount = min(max(0, ed - (outputLength - inputSize)),
proximityMatchedCount); proximityMatchedCount);
if (transposedCount <= 0) { if (transposedCount <= 0) {
if (ed == 1 && (inputLength == outputLength - 1 || inputLength == outputLength + 1)) { if (ed == 1 && (inputSize == outputLength - 1 || inputSize == outputLength + 1)) {
// Promote a word with just one skipped or excessive char // Promote a word with just one skipped or excessive char
if (sameLength) { if (sameLength) {
multiplyRate(WORDS_WITH_JUST_ONE_CORRECTION_PROMOTION_RATE multiplyRate(WORDS_WITH_JUST_ONE_CORRECTION_PROMOTION_RATE
@ -740,8 +740,8 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex
// Demotion for a word with missing character // Demotion for a word with missing character
if (skipped) { if (skipped) {
const int demotionRate = WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE const int demotionRate = WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE
* (10 * inputLength - WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X) * (10 * inputSize - WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X)
/ (10 * inputLength / (10 * inputSize
- WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X + 10); - WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X + 10);
if (DEBUG_DICT_FULL) { if (DEBUG_DICT_FULL) {
AKLOGI("Demotion rate for missing character is %d.", demotionRate); AKLOGI("Demotion rate for missing character is %d.", demotionRate);
@ -843,7 +843,7 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex
? adjustedProximityMatchedCount ? adjustedProximityMatchedCount
: (proximityMatchedCount + transposedCount); : (proximityMatchedCount + transposedCount);
multiplyRate( multiplyRate(
100 - CORRECTION_COUNT_RATE_DEMOTION_RATE_BASE * errorCount / inputLength, &finalFreq); 100 - CORRECTION_COUNT_RATE_DEMOTION_RATE_BASE * errorCount / inputSize, &finalFreq);
// Promotion for an exactly matched word // Promotion for an exactly matched word
if (ed == 0) { if (ed == 0) {
@ -878,7 +878,7 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex
e ... exceeding e ... exceeding
p ... proximity matching p ... proximity matching
*/ */
if (matchCount == inputLength && matchCount >= 2 && !skipped if (matchCount == inputSize && matchCount >= 2 && !skipped
&& word[matchCount] == word[matchCount - 1]) { && word[matchCount] == word[matchCount - 1]) {
multiplyRate(WORDS_WITH_MATCH_SKIP_PROMOTION_RATE, &finalFreq); multiplyRate(WORDS_WITH_MATCH_SKIP_PROMOTION_RATE, &finalFreq);
} }
@ -888,8 +888,8 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex
multiplyIntCapped(fullWordMultiplier, &finalFreq); multiplyIntCapped(fullWordMultiplier, &finalFreq);
} }
if (useFullEditDistance && outputLength > inputLength + 1) { if (useFullEditDistance && outputLength > inputSize + 1) {
const int diff = outputLength - inputLength - 1; const int diff = outputLength - inputSize - 1;
const int divider = diff < 31 ? 1 << diff : S_INT_MAX; const int divider = diff < 31 ? 1 << diff : S_INT_MAX;
finalFreq = divider > finalFreq ? 1 : finalFreq / divider; finalFreq = divider > finalFreq ? 1 : finalFreq / divider;
} }
@ -899,8 +899,8 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex
} }
if (DEBUG_CORRECTION_FREQ if (DEBUG_CORRECTION_FREQ
&& (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == inputLength)) { && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == inputSize)) {
DUMP_WORD(correction->getPrimaryInputWord(), inputLength); DUMP_WORD(correction->getPrimaryInputWord(), inputSize);
DUMP_WORD(correction->mWord, outputLength); DUMP_WORD(correction->mWord, outputLength);
AKLOGI("FinalFreq: [P%d, S%d, T%d, E%d, A%d] %d, %d, %d, %d, %d, %d", proximityMatchedCount, AKLOGI("FinalFreq: [P%d, S%d, T%d, E%d, A%d] %d, %d, %d, %d, %d, %d", proximityMatchedCount,
skippedCount, transposedCount, excessiveCount, additionalProximityCount, skippedCount, transposedCount, excessiveCount, additionalProximityCount,

View File

@ -42,7 +42,7 @@ class Correction {
virtual ~Correction(); virtual ~Correction();
void resetCorrection(); void resetCorrection();
void initCorrection( void initCorrection(
const ProximityInfo *pi, const int inputLength, const int maxWordLength); const ProximityInfo *pi, const int inputSize, const int maxWordLength);
void initCorrectionState(const int rootPos, const int childCount, const bool traverseAll); void initCorrectionState(const int rootPos, const int childCount, const bool traverseAll);
// TODO: remove // TODO: remove
@ -66,7 +66,7 @@ class Correction {
const bool isSpaceProximity, const unsigned short *word); const bool isSpaceProximity, const unsigned short *word);
int getFinalProbability(const int probability, unsigned short **word, int *wordLength); int getFinalProbability(const int probability, unsigned short **word, int *wordLength);
int getFinalProbabilityForSubQueue(const int probability, unsigned short **word, int getFinalProbabilityForSubQueue(const int probability, unsigned short **word,
int *wordLength, const int inputLength); int *wordLength, const int inputSize);
CorrectionType processCharAndCalcState(const int32_t c, const bool isTerminal); CorrectionType processCharAndCalcState(const int32_t c, const bool isTerminal);
@ -90,7 +90,7 @@ class Correction {
public: public:
static int calculateFinalProbability(const int inputIndex, const int depth, static int calculateFinalProbability(const int inputIndex, const int depth,
const int probability, int *editDistanceTable, const Correction *correction, const int probability, int *editDistanceTable, const Correction *correction,
const int inputLength); const int inputSize);
static int calcFreqForSplitMultipleWords(const int *freqArray, const int *wordLengthArray, static int calcFreqForSplitMultipleWords(const int *freqArray, const int *wordLengthArray,
const int wordCount, const Correction *correction, const bool isSpaceProximity, const int wordCount, const Correction *correction, const bool isSpaceProximity,
const unsigned short *word); const unsigned short *word);
@ -105,9 +105,9 @@ class Correction {
// proximity info state // proximity info state
void initInputParams(const ProximityInfo *proximityInfo, const int32_t *inputCodes, void initInputParams(const ProximityInfo *proximityInfo, const int32_t *inputCodes,
const int inputLength, const int *xCoordinates, const int *yCoordinates) { const int inputSize, const int *xCoordinates, const int *yCoordinates) {
mProximityInfoState.initInputParams( mProximityInfoState.initInputParams(0, MAX_POINT_TO_KEY_LENGTH,
proximityInfo, inputCodes, inputLength, xCoordinates, yCoordinates); proximityInfo, inputCodes, inputSize, xCoordinates, yCoordinates, 0, 0, false);
} }
const unsigned short *getPrimaryInputWord() const { const unsigned short *getPrimaryInputWord() const {
@ -204,7 +204,7 @@ class Correction {
inline CorrectionType processUnrelatedCorrectionType(); inline CorrectionType processUnrelatedCorrectionType();
inline void addCharToCurrentWord(const int32_t c); inline void addCharToCurrentWord(const int32_t c);
inline int getFinalProbabilityInternal(const int probability, unsigned short **word, inline int getFinalProbabilityInternal(const int probability, unsigned short **word,
int *wordLength, const int inputLength); int *wordLength, const int inputSize);
static const int TYPED_LETTER_MULTIPLIER = 2; static const int TYPED_LETTER_MULTIPLIER = 2;
static const int FULL_WORD_MULTIPLIER = 2; static const int FULL_WORD_MULTIPLIER = 2;
@ -214,7 +214,7 @@ class Correction {
bool mDoAutoCompletion; bool mDoAutoCompletion;
int mMaxEditDistance; int mMaxEditDistance;
int mMaxDepth; int mMaxDepth;
int mInputLength; int mInputSize;
int mSpaceProximityPos; int mSpaceProximityPos;
int mMissingSpacePos; int mMissingSpacePos;
int mTerminalInputIndex; int mTerminalInputIndex;

View File

@ -294,6 +294,9 @@ static inline void prof_out(void) {
#define MAX_SPACES_INTERNAL 16 #define MAX_SPACES_INTERNAL 16
// Max Distance between point to key
#define MAX_POINT_TO_KEY_LENGTH 10000000
// TODO: Reduce this constant if possible; check the maximum number of digraphs in the same // TODO: Reduce this constant if possible; check the maximum number of digraphs in the same
// word in the dictionary for languages with digraphs, like German and French // word in the dictionary for languages with digraphs, like German and French
#define DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH 5 #define DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH 5

View File

@ -19,7 +19,6 @@
#include <cmath> #include <cmath>
#define MAX_DISTANCE 10000000
#define MAX_PATHS 2 #define MAX_PATHS 2
#define DEBUG_DECODER false #define DEBUG_DECODER false

View File

@ -20,13 +20,15 @@
#define LOG_TAG "LatinIME: proximity_info_state.cpp" #define LOG_TAG "LatinIME: proximity_info_state.cpp"
#include "defines.h" #include "defines.h"
#include "geometry_utils.h"
#include "proximity_info.h" #include "proximity_info.h"
#include "proximity_info_state.h" #include "proximity_info_state.h"
namespace latinime { namespace latinime {
void ProximityInfoState::initInputParams( void ProximityInfoState::initInputParams(const int pointerId, const float maxLength,
const ProximityInfo *proximityInfo, const int32_t *inputCodes, const int inputLength, const ProximityInfo *proximityInfo, const int32_t *inputCodes, const int inputSize,
const int *xCoordinates, const int *yCoordinates) { const int *const xCoordinates, const int *const yCoordinates, const int *const times,
const int *const pointerIds, const bool isGeometric) {
mProximityInfo = proximityInfo; mProximityInfo = proximityInfo;
mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData(); mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData();
mMostCommonKeyWidthSquare = proximityInfo->getMostCommonKeyWidthSquare(); mMostCommonKeyWidthSquare = proximityInfo->getMostCommonKeyWidthSquare();
@ -45,7 +47,7 @@ void ProximityInfoState::initInputParams(
memset(mInputCodes, 0, memset(mInputCodes, 0,
MAX_WORD_LENGTH_INTERNAL * MAX_PROXIMITY_CHARS_SIZE_INTERNAL * sizeof(mInputCodes[0])); MAX_WORD_LENGTH_INTERNAL * MAX_PROXIMITY_CHARS_SIZE_INTERNAL * sizeof(mInputCodes[0]));
for (int i = 0; i < inputLength; ++i) { for (int i = 0; i < inputSize; ++i) {
const int32_t primaryKey = inputCodes[i]; const int32_t primaryKey = inputCodes[i];
const int x = xCoordinates[i]; const int x = xCoordinates[i];
const int y = yCoordinates[i]; const int y = yCoordinates[i];
@ -54,7 +56,7 @@ void ProximityInfoState::initInputParams(
} }
if (DEBUG_PROXIMITY_CHARS) { if (DEBUG_PROXIMITY_CHARS) {
for (int i = 0; i < inputLength; ++i) { for (int i = 0; i < inputSize; ++i) {
AKLOGI("---"); AKLOGI("---");
for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL; ++j) { for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL; ++j) {
int icc = mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j]; int icc = mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j];
@ -65,19 +67,57 @@ void ProximityInfoState::initInputParams(
} }
} }
} }
mInputXCoordinates = xCoordinates;
mInputYCoordinates = yCoordinates; mMaxPointToKeyLength = maxLength;
mTouchPositionCorrectionEnabled = ///////////////////////
mHasTouchPositionCorrectionData && xCoordinates && yCoordinates; // Setup touch points
mInputLength = inputLength; mInputXs.clear();
for (int i = 0; i < inputLength; ++i) { mInputYs.clear();
mTimes.clear();
mLengthCache.clear();
mDistanceCache.clear();
mInputSize = 0;
if (xCoordinates && yCoordinates) {
const bool proximityOnly = !isGeometric && (xCoordinates[0] < 0 || yCoordinates[0] < 0);
for (int i = 0; i < inputSize; ++i) {
++mInputSize;
// Assuming pointerId == 0 if pointerIds is null.
const int pid = pointerIds ? pointerIds[i] : 0;
if (pointerId == pid) {
const int c = isGeometric ? NOT_A_COORDINATE : getPrimaryCharAt(i);
const int x = proximityOnly ? NOT_A_COORDINATE : xCoordinates[i];
const int y = proximityOnly ? NOT_A_COORDINATE : yCoordinates[i];
const int time = times ? times[i] : -1;
pushTouchPoint(c, x, y, time, isGeometric);
}
}
}
if (mInputSize > 0) {
const int keyCount = mProximityInfo->getKeyCount();
mDistanceCache.resize(mInputSize * keyCount);
for (int i = 0; i < mInputSize; ++i) {
for (int k = 0; k < keyCount; ++k) {
const int index = i * keyCount + k;
const int x = mInputXs[i];
const int y = mInputYs[i];
mDistanceCache[index] =
mProximityInfo->getNormalizedSquaredDistanceFromCenterFloat(k, x, y);
}
}
}
// end
///////////////////////
for (int i = 0; i < inputSize; ++i) {
mPrimaryInputWord[i] = getPrimaryCharAt(i); mPrimaryInputWord[i] = getPrimaryCharAt(i);
} }
mPrimaryInputWord[inputLength] = 0; mPrimaryInputWord[inputSize] = 0;
if (DEBUG_PROXIMITY_CHARS) {
AKLOGI("--- initInputParams"); mTouchPositionCorrectionEnabled =
} mHasTouchPositionCorrectionData && xCoordinates && yCoordinates && !isGeometric;
for (int i = 0; i < mInputLength; ++i) { for (int i = 0; i < mInputSize && mTouchPositionCorrectionEnabled; ++i) {
const int *proximityChars = getProximityCharsAt(i); const int *proximityChars = getProximityCharsAt(i);
const int primaryKey = proximityChars[0]; const int primaryKey = proximityChars[0];
const int x = xCoordinates[i]; const int x = xCoordinates[i];
@ -108,6 +148,32 @@ void ProximityInfoState::initInputParams(
} }
} }
void ProximityInfoState::pushTouchPoint(const int nodeChar, int x, int y,
const int time, const bool sample) {
const uint32_t size = mInputXs.size();
// TODO: Should have a const variable for 10
const int sampleRate = mProximityInfo->getMostCommonKeyWidth() / 10;
if (size > 0) {
const int dist = getDistanceInt(x, y, mInputXs[size - 1], mInputYs[size - 1]);
if (sample && dist < sampleRate) {
return;
}
mLengthCache.push_back(mLengthCache[size - 1] + dist);
} else {
mLengthCache.push_back(0);
}
if (nodeChar >= 0 && (x < 0 || y < 0)) {
const int keyId = mProximityInfo->getKeyIndex(nodeChar);
if (keyId >= 0) {
x = mProximityInfo->getKeyCenterXOfIdG(keyId);
y = mProximityInfo->getKeyCenterYOfIdG(keyId);
}
}
mInputXs.push_back(x);
mInputYs.push_back(y);
mTimes.push_back(time);
}
float ProximityInfoState::calculateNormalizedSquaredDistance( float ProximityInfoState::calculateNormalizedSquaredDistance(
const int keyIndex, const int inputIndex) const { const int keyIndex, const int inputIndex) const {
if (keyIndex == NOT_AN_INDEX) { if (keyIndex == NOT_AN_INDEX) {
@ -116,7 +182,7 @@ float ProximityInfoState::calculateNormalizedSquaredDistance(
if (!mProximityInfo->hasSweetSpotData(keyIndex)) { if (!mProximityInfo->hasSweetSpotData(keyIndex)) {
return NOT_A_DISTANCE_FLOAT; return NOT_A_DISTANCE_FLOAT;
} }
if (NOT_A_COORDINATE == mInputXCoordinates[inputIndex]) { if (NOT_A_COORDINATE == mInputXs[inputIndex]) {
return NOT_A_DISTANCE_FLOAT; return NOT_A_DISTANCE_FLOAT;
} }
const float squaredDistance = calculateSquaredDistanceFromSweetSpotCenter( const float squaredDistance = calculateSquaredDistanceFromSweetSpotCenter(
@ -125,12 +191,37 @@ float ProximityInfoState::calculateNormalizedSquaredDistance(
return squaredDistance / squaredRadius; return squaredDistance / squaredRadius;
} }
int ProximityInfoState::getDuration(const int index) const {
if (mTimes.size() == 0 || index <= 0 || index >= static_cast<int>(mInputSize) - 1) {
return 0;
}
return mTimes[index + 1] - mTimes[index - 1];
}
float ProximityInfoState::getPointToKeyLength(int inputIndex, int charCode, float scale) {
const int keyId = mProximityInfo->getKeyIndex(charCode);
if (keyId >= 0) {
const int index = inputIndex * mProximityInfo->getKeyCount() + keyId;
return min(mDistanceCache[index] * scale, mMaxPointToKeyLength);
}
return 0;
}
int ProximityInfoState::getKeyKeyDistance(int key0, int key1) {
return mProximityInfo->getKeyKeyDistanceG(key0, key1);
}
int ProximityInfoState::getSpaceY() {
const int keyId = mProximityInfo->getKeyIndex(' ');
return mProximityInfo->getKeyCenterYOfIdG(keyId);
}
float ProximityInfoState::calculateSquaredDistanceFromSweetSpotCenter( float ProximityInfoState::calculateSquaredDistanceFromSweetSpotCenter(
const int keyIndex, const int inputIndex) const { const int keyIndex, const int inputIndex) const {
const float sweetSpotCenterX = mProximityInfo->getSweetSpotCenterXAt(keyIndex); const float sweetSpotCenterX = mProximityInfo->getSweetSpotCenterXAt(keyIndex);
const float sweetSpotCenterY = mProximityInfo->getSweetSpotCenterYAt(keyIndex); const float sweetSpotCenterY = mProximityInfo->getSweetSpotCenterYAt(keyIndex);
const float inputX = static_cast<float>(mInputXCoordinates[inputIndex]); const float inputX = static_cast<float>(mInputXs[inputIndex]);
const float inputY = static_cast<float>(mInputYCoordinates[inputIndex]); const float inputY = static_cast<float>(mInputYs[inputIndex]);
return square(inputX - sweetSpotCenterX) + square(inputY - sweetSpotCenterY); return square(inputX - sweetSpotCenterX) + square(inputY - sweetSpotCenterY);
} }
} // namespace latinime } // namespace latinime

View File

@ -19,6 +19,7 @@
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <vector>
#include "char_utils.h" #include "char_utils.h"
#include "defines.h" #include "defines.h"
@ -40,9 +41,10 @@ class ProximityInfoState {
///////////////////////////////////////// /////////////////////////////////////////
// Defined in proximity_info_state.cpp // // Defined in proximity_info_state.cpp //
///////////////////////////////////////// /////////////////////////////////////////
void initInputParams( void initInputParams(const int pointerId, const float maxLength,
const ProximityInfo *proximityInfo, const int32_t *inputCodes, const int inputLength, const ProximityInfo *proximityInfo, const int32_t *inputCodes, const int inputSize,
const int *xCoordinates, const int *yCoordinates); const int *xCoordinates, const int *yCoordinates, const int *const times,
const int *const pointerIds, const bool isGeometric);
///////////////////////////////////////// /////////////////////////////////////////
// Defined here // // Defined here //
@ -65,14 +67,14 @@ class ProximityInfoState {
} }
inline bool existsAdjacentProximityChars(const int index) const { inline bool existsAdjacentProximityChars(const int index) const {
if (index < 0 || index >= mInputLength) return false; if (index < 0 || index >= mInputSize) return false;
const int currentChar = getPrimaryCharAt(index); const int currentChar = getPrimaryCharAt(index);
const int leftIndex = index - 1; const int leftIndex = index - 1;
if (leftIndex >= 0 && existsCharInProximityAt(leftIndex, currentChar)) { if (leftIndex >= 0 && existsCharInProximityAt(leftIndex, currentChar)) {
return true; return true;
} }
const int rightIndex = index + 1; const int rightIndex = index + 1;
if (rightIndex < mInputLength && existsCharInProximityAt(rightIndex, currentChar)) { if (rightIndex < mInputSize && existsCharInProximityAt(rightIndex, currentChar)) {
return true; return true;
} }
return false; return false;
@ -158,7 +160,7 @@ class ProximityInfoState {
} }
inline bool sameAsTyped(const unsigned short *word, int length) const { inline bool sameAsTyped(const unsigned short *word, int length) const {
if (length != mInputLength) { if (length != mInputSize) {
return false; return false;
} }
const int *inputCodes = mInputCodes; const int *inputCodes = mInputCodes;
@ -172,6 +174,18 @@ class ProximityInfoState {
return true; return true;
} }
int getDuration(const int index) const;
bool isUsed() const {
return mInputSize > 0;
}
float getPointToKeyLength(int inputIndex, int charCode, float scale);
int getKeyKeyDistance(int key0, int key1);
int getSpaceY();
private: private:
DISALLOW_COPY_AND_ASSIGN(ProximityInfoState); DISALLOW_COPY_AND_ASSIGN(ProximityInfoState);
///////////////////////////////////////// /////////////////////////////////////////
@ -182,13 +196,14 @@ class ProximityInfoState {
float calculateSquaredDistanceFromSweetSpotCenter( float calculateSquaredDistanceFromSweetSpotCenter(
const int keyIndex, const int inputIndex) const; const int keyIndex, const int inputIndex) const;
void pushTouchPoint(const int nodeChar, int x, int y, const int time, const bool sample);
///////////////////////////////////////// /////////////////////////////////////////
// Defined here // // Defined here //
///////////////////////////////////////// /////////////////////////////////////////
inline float square(const float x) const { return x * x; } inline float square(const float x) const { return x * x; }
bool hasInputCoordinates() const { bool hasInputCoordinates() const {
return mInputXCoordinates && mInputYCoordinates; return mInputXs.size() > 0 && mInputYs.size() > 0;
} }
inline const int *getProximityCharsAt(const int index) const { inline const int *getProximityCharsAt(const int index) const {
@ -197,6 +212,7 @@ class ProximityInfoState {
// const // const
const ProximityInfo *mProximityInfo; const ProximityInfo *mProximityInfo;
float mMaxPointToKeyLength;
bool mHasTouchPositionCorrectionData; bool mHasTouchPositionCorrectionData;
int mMostCommonKeyWidthSquare; int mMostCommonKeyWidthSquare;
std::string mLocaleStr; std::string mLocaleStr;
@ -206,12 +222,15 @@ class ProximityInfoState {
int mGridHeight; int mGridHeight;
int mGridWidth; int mGridWidth;
const int *mInputXCoordinates; std::vector<int> mInputXs;
const int *mInputYCoordinates; std::vector<int> mInputYs;
std::vector<int> mTimes;
std::vector<float> mDistanceCache;
std::vector<int> mLengthCache;
bool mTouchPositionCorrectionEnabled; bool mTouchPositionCorrectionEnabled;
int32_t mInputCodes[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH_INTERNAL]; int32_t mInputCodes[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH_INTERNAL];
int mNormalizedSquaredDistances[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH_INTERNAL]; int mNormalizedSquaredDistances[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH_INTERNAL];
int mInputLength; int mInputSize;
unsigned short mPrimaryInputWord[MAX_WORD_LENGTH_INTERNAL]; unsigned short mPrimaryInputWord[MAX_WORD_LENGTH_INTERNAL];
}; };
} // namespace latinime } // namespace latinime

View File

@ -237,7 +237,7 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo,
void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo, void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo,
const int *xcoordinates, const int *ycoordinates, const int *codes, const int *xcoordinates, const int *ycoordinates, const int *codes,
const int inputLength, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, const int inputSize, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter,
const bool useFullEditDistance, Correction *correction, const bool useFullEditDistance, Correction *correction,
WordsPriorityQueuePool *queuePool) const { WordsPriorityQueuePool *queuePool) const {
@ -247,7 +247,7 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo,
PROF_START(1); PROF_START(1);
getOneWordSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, bigramMap, bigramFilter, getOneWordSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, bigramMap, bigramFilter,
useFullEditDistance, inputLength, correction, queuePool); useFullEditDistance, inputSize, correction, queuePool);
PROF_END(1); PROF_END(1);
PROF_START(2); PROF_START(2);
@ -263,7 +263,7 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo,
WordsPriorityQueue *masterQueue = queuePool->getMasterQueue(); WordsPriorityQueue *masterQueue = queuePool->getMasterQueue();
if (masterQueue->size() > 0) { if (masterQueue->size() > 0) {
float nsForMaster = masterQueue->getHighestNormalizedScore( float nsForMaster = masterQueue->getHighestNormalizedScore(
correction->getPrimaryInputWord(), inputLength, 0, 0, 0); correction->getPrimaryInputWord(), inputSize, 0, 0, 0);
hasAutoCorrectionCandidate = (nsForMaster > START_TWO_WORDS_CORRECTION_THRESHOLD); hasAutoCorrectionCandidate = (nsForMaster > START_TWO_WORDS_CORRECTION_THRESHOLD);
} }
PROF_END(4); PROF_END(4);
@ -271,9 +271,9 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo,
PROF_START(5); PROF_START(5);
// Multiple word suggestions // Multiple word suggestions
if (SUGGEST_MULTIPLE_WORDS if (SUGGEST_MULTIPLE_WORDS
&& inputLength >= MIN_USER_TYPED_LENGTH_FOR_MULTIPLE_WORD_SUGGESTION) { && inputSize >= MIN_USER_TYPED_LENGTH_FOR_MULTIPLE_WORD_SUGGESTION) {
getSplitMultipleWordsSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, getSplitMultipleWordsSuggestions(proximityInfo, xcoordinates, ycoordinates, codes,
useFullEditDistance, inputLength, correction, queuePool, useFullEditDistance, inputSize, correction, queuePool,
hasAutoCorrectionCandidate); hasAutoCorrectionCandidate);
} }
PROF_END(5); PROF_END(5);
@ -304,15 +304,15 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo,
} }
void UnigramDictionary::initSuggestions(ProximityInfo *proximityInfo, const int *xCoordinates, void UnigramDictionary::initSuggestions(ProximityInfo *proximityInfo, const int *xCoordinates,
const int *yCoordinates, const int *codes, const int inputLength, const int *yCoordinates, const int *codes, const int inputSize,
Correction *correction) const { Correction *correction) const {
if (DEBUG_DICT) { if (DEBUG_DICT) {
AKLOGI("initSuggest"); AKLOGI("initSuggest");
DUMP_WORD_INT(codes, inputLength); DUMP_WORD_INT(codes, inputSize);
} }
correction->initInputParams(proximityInfo, codes, inputLength, xCoordinates, yCoordinates); correction->initInputParams(proximityInfo, codes, inputSize, xCoordinates, yCoordinates);
const int maxDepth = min(inputLength * MAX_DEPTH_MULTIPLIER, MAX_WORD_LENGTH); const int maxDepth = min(inputSize * MAX_DEPTH_MULTIPLIER, MAX_WORD_LENGTH);
correction->initCorrection(proximityInfo, inputLength, maxDepth); correction->initCorrection(proximityInfo, inputSize, maxDepth);
} }
static const char QUOTE = '\''; static const char QUOTE = '\'';
@ -321,15 +321,15 @@ static const char SPACE = ' ';
void UnigramDictionary::getOneWordSuggestions(ProximityInfo *proximityInfo, void UnigramDictionary::getOneWordSuggestions(ProximityInfo *proximityInfo,
const int *xcoordinates, const int *ycoordinates, const int *codes, const int *xcoordinates, const int *ycoordinates, const int *codes,
const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter,
const bool useFullEditDistance, const int inputLength, const bool useFullEditDistance, const int inputSize,
Correction *correction, WordsPriorityQueuePool *queuePool) const { Correction *correction, WordsPriorityQueuePool *queuePool) const {
initSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, inputLength, correction); initSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, inputSize, correction);
getSuggestionCandidates(useFullEditDistance, inputLength, bigramMap, bigramFilter, correction, getSuggestionCandidates(useFullEditDistance, inputSize, bigramMap, bigramFilter, correction,
queuePool, true /* doAutoCompletion */, DEFAULT_MAX_ERRORS, FIRST_WORD_INDEX); queuePool, true /* doAutoCompletion */, DEFAULT_MAX_ERRORS, FIRST_WORD_INDEX);
} }
void UnigramDictionary::getSuggestionCandidates(const bool useFullEditDistance, void UnigramDictionary::getSuggestionCandidates(const bool useFullEditDistance,
const int inputLength, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, const int inputSize, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter,
Correction *correction, WordsPriorityQueuePool *queuePool, Correction *correction, WordsPriorityQueuePool *queuePool,
const bool doAutoCompletion, const int maxErrors, const int currentWordIndex) const { const bool doAutoCompletion, const int maxErrors, const int currentWordIndex) const {
uint8_t totalTraverseCount = correction->pushAndGetTotalTraverseCount(); uint8_t totalTraverseCount = correction->pushAndGetTotalTraverseCount();
@ -351,7 +351,7 @@ void UnigramDictionary::getSuggestionCandidates(const bool useFullEditDistance,
int childCount = BinaryFormat::getGroupCountAndForwardPointer(DICT_ROOT, &rootPosition); int childCount = BinaryFormat::getGroupCountAndForwardPointer(DICT_ROOT, &rootPosition);
int outputIndex = 0; int outputIndex = 0;
correction->initCorrectionState(rootPosition, childCount, (inputLength <= 0)); correction->initCorrectionState(rootPosition, childCount, (inputSize <= 0));
// Depth first search // Depth first search
while (outputIndex >= 0) { while (outputIndex >= 0) {
@ -446,7 +446,7 @@ inline void UnigramDictionary::onTerminal(const int probability,
int UnigramDictionary::getSubStringSuggestion( int UnigramDictionary::getSubStringSuggestion(
ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates,
const int *codes, const bool useFullEditDistance, Correction *correction, const int *codes, const bool useFullEditDistance, Correction *correction,
WordsPriorityQueuePool *queuePool, const int inputLength, WordsPriorityQueuePool *queuePool, const int inputSize,
const bool hasAutoCorrectionCandidate, const int currentWordIndex, const bool hasAutoCorrectionCandidate, const int currentWordIndex,
const int inputWordStartPos, const int inputWordLength, const int inputWordStartPos, const int inputWordLength,
const int outputWordStartPos, const bool isSpaceProximity, int *freqArray, const int outputWordStartPos, const bool isSpaceProximity, int *freqArray,
@ -497,7 +497,7 @@ int UnigramDictionary::getSubStringSuggestion(
int nextWordLength = 0; int nextWordLength = 0;
// TODO: Optimize init suggestion // TODO: Optimize init suggestion
initSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, initSuggestions(proximityInfo, xcoordinates, ycoordinates, codes,
inputLength, correction); inputSize, correction);
unsigned short word[MAX_WORD_LENGTH_INTERNAL]; unsigned short word[MAX_WORD_LENGTH_INTERNAL];
int freq = getMostFrequentWordLike( int freq = getMostFrequentWordLike(
@ -566,7 +566,7 @@ int UnigramDictionary::getSubStringSuggestion(
*outputWordLength = tempOutputWordLength; *outputWordLength = tempOutputWordLength;
} }
if ((inputWordStartPos + inputWordLength) < inputLength) { if ((inputWordStartPos + inputWordLength) < inputSize) {
if (outputWordStartPos + nextWordLength >= MAX_WORD_LENGTH) { if (outputWordStartPos + nextWordLength >= MAX_WORD_LENGTH) {
return FLAG_MULTIPLE_SUGGEST_SKIP; return FLAG_MULTIPLE_SUGGEST_SKIP;
} }
@ -585,7 +585,7 @@ int UnigramDictionary::getSubStringSuggestion(
freqArray[i], wordLengthArray[i]); freqArray[i], wordLengthArray[i]);
} }
AKLOGI("Split two words: freq = %d, length = %d, %d, isSpace ? %d", pairFreq, AKLOGI("Split two words: freq = %d, length = %d, %d, isSpace ? %d", pairFreq,
inputLength, tempOutputWordLength, isSpaceProximity); inputSize, tempOutputWordLength, isSpaceProximity);
} }
addWord(outputWord, tempOutputWordLength, pairFreq, queuePool->getMasterQueue(), addWord(outputWord, tempOutputWordLength, pairFreq, queuePool->getMasterQueue(),
Dictionary::KIND_CORRECTION); Dictionary::KIND_CORRECTION);
@ -595,7 +595,7 @@ int UnigramDictionary::getSubStringSuggestion(
void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo, void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo,
const int *xcoordinates, const int *ycoordinates, const int *codes, const int *xcoordinates, const int *ycoordinates, const int *codes,
const bool useFullEditDistance, const int inputLength, const bool useFullEditDistance, const int inputSize,
Correction *correction, WordsPriorityQueuePool *queuePool, Correction *correction, WordsPriorityQueuePool *queuePool,
const bool hasAutoCorrectionCandidate, const int startInputPos, const int startWordIndex, const bool hasAutoCorrectionCandidate, const int startInputPos, const int startWordIndex,
const int outputWordLength, int *freqArray, int *wordLengthArray, const int outputWordLength, int *freqArray, int *wordLengthArray,
@ -606,11 +606,11 @@ void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo,
} }
if (startWordIndex >= 1 if (startWordIndex >= 1
&& (hasAutoCorrectionCandidate && (hasAutoCorrectionCandidate
|| inputLength < MIN_INPUT_LENGTH_FOR_THREE_OR_MORE_WORDS_CORRECTION)) { || inputSize < MIN_INPUT_LENGTH_FOR_THREE_OR_MORE_WORDS_CORRECTION)) {
// Do not suggest 3+ words if already has auto correction candidate // Do not suggest 3+ words if already has auto correction candidate
return; return;
} }
for (int i = startInputPos + 1; i < inputLength; ++i) { for (int i = startInputPos + 1; i < inputSize; ++i) {
if (DEBUG_CORRECTION_FREQ) { if (DEBUG_CORRECTION_FREQ) {
AKLOGI("Multi words(%d), start in %d sep %d start out %d", AKLOGI("Multi words(%d), start in %d sep %d start out %d",
startWordIndex, startInputPos, i, outputWordLength); startWordIndex, startInputPos, i, outputWordLength);
@ -621,7 +621,7 @@ void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo,
int inputWordStartPos = startInputPos; int inputWordStartPos = startInputPos;
int inputWordLength = i - startInputPos; int inputWordLength = i - startInputPos;
const int suggestionFlag = getSubStringSuggestion(proximityInfo, xcoordinates, ycoordinates, const int suggestionFlag = getSubStringSuggestion(proximityInfo, xcoordinates, ycoordinates,
codes, useFullEditDistance, correction, queuePool, inputLength, codes, useFullEditDistance, correction, queuePool, inputSize,
hasAutoCorrectionCandidate, startWordIndex, inputWordStartPos, inputWordLength, hasAutoCorrectionCandidate, startWordIndex, inputWordStartPos, inputWordLength,
outputWordLength, true /* not used */, freqArray, wordLengthArray, outputWord, outputWordLength, true /* not used */, freqArray, wordLengthArray, outputWord,
&tempOutputWordLength); &tempOutputWordLength);
@ -638,14 +638,14 @@ void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo,
// Next word // Next word
// Missing space // Missing space
inputWordStartPos = i; inputWordStartPos = i;
inputWordLength = inputLength - i; inputWordLength = inputSize - i;
if(getSubStringSuggestion(proximityInfo, xcoordinates, ycoordinates, codes, if(getSubStringSuggestion(proximityInfo, xcoordinates, ycoordinates, codes,
useFullEditDistance, correction, queuePool, inputLength, hasAutoCorrectionCandidate, useFullEditDistance, correction, queuePool, inputSize, hasAutoCorrectionCandidate,
startWordIndex + 1, inputWordStartPos, inputWordLength, tempOutputWordLength, startWordIndex + 1, inputWordStartPos, inputWordLength, tempOutputWordLength,
false /* missing space */, freqArray, wordLengthArray, outputWord, 0) false /* missing space */, freqArray, wordLengthArray, outputWord, 0)
!= FLAG_MULTIPLE_SUGGEST_CONTINUE) { != FLAG_MULTIPLE_SUGGEST_CONTINUE) {
getMultiWordsSuggestionRec(proximityInfo, xcoordinates, ycoordinates, codes, getMultiWordsSuggestionRec(proximityInfo, xcoordinates, ycoordinates, codes,
useFullEditDistance, inputLength, correction, queuePool, useFullEditDistance, inputSize, correction, queuePool,
hasAutoCorrectionCandidate, inputWordStartPos, startWordIndex + 1, hasAutoCorrectionCandidate, inputWordStartPos, startWordIndex + 1,
tempOutputWordLength, freqArray, wordLengthArray, outputWord); tempOutputWordLength, freqArray, wordLengthArray, outputWord);
} }
@ -668,7 +668,7 @@ void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo,
AKLOGI("Do mistyped space correction"); AKLOGI("Do mistyped space correction");
} }
getSubStringSuggestion(proximityInfo, xcoordinates, ycoordinates, codes, getSubStringSuggestion(proximityInfo, xcoordinates, ycoordinates, codes,
useFullEditDistance, correction, queuePool, inputLength, hasAutoCorrectionCandidate, useFullEditDistance, correction, queuePool, inputSize, hasAutoCorrectionCandidate,
startWordIndex + 1, inputWordStartPos, inputWordLength, tempOutputWordLength, startWordIndex + 1, inputWordStartPos, inputWordLength, tempOutputWordLength,
true /* mistyped space */, freqArray, wordLengthArray, outputWord, 0); true /* mistyped space */, freqArray, wordLengthArray, outputWord, 0);
} }
@ -676,10 +676,10 @@ void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo,
void UnigramDictionary::getSplitMultipleWordsSuggestions(ProximityInfo *proximityInfo, void UnigramDictionary::getSplitMultipleWordsSuggestions(ProximityInfo *proximityInfo,
const int *xcoordinates, const int *ycoordinates, const int *codes, const int *xcoordinates, const int *ycoordinates, const int *codes,
const bool useFullEditDistance, const int inputLength, const bool useFullEditDistance, const int inputSize,
Correction *correction, WordsPriorityQueuePool *queuePool, Correction *correction, WordsPriorityQueuePool *queuePool,
const bool hasAutoCorrectionCandidate) const { const bool hasAutoCorrectionCandidate) const {
if (inputLength >= MAX_WORD_LENGTH) return; if (inputSize >= MAX_WORD_LENGTH) return;
if (DEBUG_DICT) { if (DEBUG_DICT) {
AKLOGI("--- Suggest multiple words"); AKLOGI("--- Suggest multiple words");
} }
@ -692,7 +692,7 @@ void UnigramDictionary::getSplitMultipleWordsSuggestions(ProximityInfo *proximit
const int startInputPos = 0; const int startInputPos = 0;
const int startWordIndex = 0; const int startWordIndex = 0;
getMultiWordsSuggestionRec(proximityInfo, xcoordinates, ycoordinates, codes, getMultiWordsSuggestionRec(proximityInfo, xcoordinates, ycoordinates, codes,
useFullEditDistance, inputLength, correction, queuePool, hasAutoCorrectionCandidate, useFullEditDistance, inputSize, correction, queuePool, hasAutoCorrectionCandidate,
startInputPos, startWordIndex, outputWordLength, freqArray, wordLengthArray, startInputPos, startWordIndex, outputWordLength, freqArray, wordLengthArray,
outputWord); outputWord);
} }
@ -700,13 +700,13 @@ void UnigramDictionary::getSplitMultipleWordsSuggestions(ProximityInfo *proximit
// Wrapper for getMostFrequentWordLikeInner, which matches it to the previous // Wrapper for getMostFrequentWordLikeInner, which matches it to the previous
// interface. // interface.
inline int UnigramDictionary::getMostFrequentWordLike(const int startInputIndex, inline int UnigramDictionary::getMostFrequentWordLike(const int startInputIndex,
const int inputLength, Correction *correction, unsigned short *word) const { const int inputSize, Correction *correction, unsigned short *word) const {
uint16_t inWord[inputLength]; uint16_t inWord[inputSize];
for (int i = 0; i < inputLength; ++i) { for (int i = 0; i < inputSize; ++i) {
inWord[i] = (uint16_t)correction->getPrimaryCharAt(startInputIndex + i); inWord[i] = (uint16_t)correction->getPrimaryCharAt(startInputIndex + i);
} }
return getMostFrequentWordLikeInner(inWord, inputLength, word); return getMostFrequentWordLikeInner(inWord, inputSize, word);
} }
// This function will take the position of a character array within a CharGroup, // This function will take the position of a character array within a CharGroup,

View File

@ -53,7 +53,7 @@ class UnigramDictionary {
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(UnigramDictionary); DISALLOW_IMPLICIT_CONSTRUCTORS(UnigramDictionary);
void getWordSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates, void getWordSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
const int *ycoordinates, const int *codes, const int inputLength, const int *ycoordinates, const int *codes, const int inputSize,
const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter,
const bool useFullEditDistance, Correction *correction, const bool useFullEditDistance, Correction *correction,
WordsPriorityQueuePool *queuePool) const; WordsPriorityQueuePool *queuePool) const;
@ -72,16 +72,16 @@ class UnigramDictionary {
Correction *correction) const; Correction *correction) const;
void getOneWordSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates, void getOneWordSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
const int *ycoordinates, const int *codes, const std::map<int, int> *bigramMap, const int *ycoordinates, const int *codes, const std::map<int, int> *bigramMap,
const uint8_t *bigramFilter, const bool useFullEditDistance, const int inputLength, const uint8_t *bigramFilter, const bool useFullEditDistance, const int inputSize,
Correction *correction, WordsPriorityQueuePool *queuePool) const; Correction *correction, WordsPriorityQueuePool *queuePool) const;
void getSuggestionCandidates( void getSuggestionCandidates(
const bool useFullEditDistance, const int inputLength, const bool useFullEditDistance, const int inputSize,
const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter,
Correction *correction, WordsPriorityQueuePool *queuePool, const bool doAutoCompletion, Correction *correction, WordsPriorityQueuePool *queuePool, const bool doAutoCompletion,
const int maxErrors, const int currentWordIndex) const; const int maxErrors, const int currentWordIndex) const;
void getSplitMultipleWordsSuggestions(ProximityInfo *proximityInfo, void getSplitMultipleWordsSuggestions(ProximityInfo *proximityInfo,
const int *xcoordinates, const int *ycoordinates, const int *codes, const int *xcoordinates, const int *ycoordinates, const int *codes,
const bool useFullEditDistance, const int inputLength, const bool useFullEditDistance, const int inputSize,
Correction *correction, WordsPriorityQueuePool *queuePool, Correction *correction, WordsPriorityQueuePool *queuePool,
const bool hasAutoCorrectionCandidate) const; const bool hasAutoCorrectionCandidate) const;
void onTerminal(const int freq, const TerminalAttributes& terminalAttributes, void onTerminal(const int freq, const TerminalAttributes& terminalAttributes,
@ -92,21 +92,21 @@ class UnigramDictionary {
const uint8_t *bigramFilter, Correction *correction, int *newCount, const uint8_t *bigramFilter, Correction *correction, int *newCount,
int *newChildPosition, int *nextSiblingPosition, WordsPriorityQueuePool *queuePool, int *newChildPosition, int *nextSiblingPosition, WordsPriorityQueuePool *queuePool,
const int currentWordIndex) const; const int currentWordIndex) const;
int getMostFrequentWordLike(const int startInputIndex, const int inputLength, int getMostFrequentWordLike(const int startInputIndex, const int inputSize,
Correction *correction, unsigned short *word) const; Correction *correction, unsigned short *word) const;
int getMostFrequentWordLikeInner(const uint16_t *const inWord, const int length, int getMostFrequentWordLikeInner(const uint16_t *const inWord, const int length,
short unsigned int *outWord) const; short unsigned int *outWord) const;
int getSubStringSuggestion( int getSubStringSuggestion(
ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates,
const int *codes, const bool useFullEditDistance, Correction *correction, const int *codes, const bool useFullEditDistance, Correction *correction,
WordsPriorityQueuePool *queuePool, const int inputLength, WordsPriorityQueuePool *queuePool, const int inputSize,
const bool hasAutoCorrectionCandidate, const int currentWordIndex, const bool hasAutoCorrectionCandidate, const int currentWordIndex,
const int inputWordStartPos, const int inputWordLength, const int inputWordStartPos, const int inputWordLength,
const int outputWordStartPos, const bool isSpaceProximity, int *freqArray, const int outputWordStartPos, const bool isSpaceProximity, int *freqArray,
int *wordLengthArray, unsigned short *outputWord, int *outputWordLength) const; int *wordLengthArray, unsigned short *outputWord, int *outputWordLength) const;
void getMultiWordsSuggestionRec(ProximityInfo *proximityInfo, void getMultiWordsSuggestionRec(ProximityInfo *proximityInfo,
const int *xcoordinates, const int *ycoordinates, const int *codes, const int *xcoordinates, const int *ycoordinates, const int *codes,
const bool useFullEditDistance, const int inputLength, const bool useFullEditDistance, const int inputSize,
Correction *correction, WordsPriorityQueuePool *queuePool, Correction *correction, WordsPriorityQueuePool *queuePool,
const bool hasAutoCorrectionCandidate, const int startPos, const int startWordIndex, const bool hasAutoCorrectionCandidate, const int startPos, const int startWordIndex,
const int outputWordLength, int *freqArray, int *wordLengthArray, const int outputWordLength, int *freqArray, int *wordLengthArray,