Step 38-A Cleanup touch path
Change-Id: I9bfac98b9ac10f3812290f21673c4002241eae01main
parent
64a26b4389
commit
687a244703
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue