aboutsummaryrefslogtreecommitdiffstats
path: root/native/src
diff options
context:
space:
mode:
authorsatok <satok@google.com>2011-03-04 22:24:05 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-03-04 22:24:05 -0800
commitf9a5bfa147b07f135e8da6f9b7305c31181fa5eb (patch)
tree1d0598dc5c1309fbb8ffd7953b33aa899491e939 /native/src
parent5ac8546268a3c3cd2f523d086043d6200c553fa7 (diff)
parent817e517e463cb32726ff5a62196ac8744848e29b (diff)
downloadlatinime-f9a5bfa147b07f135e8da6f9b7305c31181fa5eb.tar.gz
latinime-f9a5bfa147b07f135e8da6f9b7305c31181fa5eb.tar.xz
latinime-f9a5bfa147b07f135e8da6f9b7305c31181fa5eb.zip
Merge "Add the suggestion algorithm of words with space proximity" into honeycomb-mr1
Diffstat (limited to 'native/src')
-rw-r--r--native/src/defines.h3
-rw-r--r--native/src/proximity_info.cpp42
-rw-r--r--native/src/proximity_info.h15
-rw-r--r--native/src/unigram_dictionary.cpp64
-rw-r--r--native/src/unigram_dictionary.h4
5 files changed, 99 insertions, 29 deletions
diff --git a/native/src/defines.h b/native/src/defines.h
index 5d85b7c51..9534f8a87 100644
--- a/native/src/defines.h
+++ b/native/src/defines.h
@@ -129,10 +129,13 @@ static void prof_out(void) {
#define DICTIONARY_HEADER_SIZE 2
#define NOT_VALID_WORD -99
+#define KEYCODE_SPACE ' '
+
#define SUGGEST_WORDS_WITH_MISSING_CHARACTER true
#define SUGGEST_WORDS_WITH_MISSING_SPACE_CHARACTER true
#define SUGGEST_WORDS_WITH_EXCESSIVE_CHARACTER true
#define SUGGEST_WORDS_WITH_TRANSPOSED_CHARACTERS true
+#define SUGGEST_WORDS_WITH_SPACE_PROXIMITY true
// The following "rate"s are used as a multiplier before dividing by 100, so they are in percent.
#define WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE 75
diff --git a/native/src/proximity_info.cpp b/native/src/proximity_info.cpp
index d0cba3eb6..5f2d09f5c 100644
--- a/native/src/proximity_info.cpp
+++ b/native/src/proximity_info.cpp
@@ -17,18 +17,48 @@
#include <stdio.h>
#include <string.h>
+#define LOG_TAG "LatinIME: proximity_info.cpp"
+
#include "proximity_info.h"
namespace latinime {
-ProximityInfo::ProximityInfo(int maxProximityCharsSize, int displayWidth, int displayHeight,
- int gridWidth, int gridHeight, uint32_t const *proximityCharsArray)
- : MAX_PROXIMITY_CHARS_SIZE(maxProximityCharsSize), DISPLAY_WIDTH(displayWidth),
- DISPLAY_HEIGHT(displayHeight), GRID_WIDTH(gridWidth), GRID_HEIGHT(gridHeight) {
- mProximityCharsArray = new uint32_t[GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE];
- memcpy(mProximityCharsArray, proximityCharsArray, sizeof(mProximityCharsArray));
+ProximityInfo::ProximityInfo(const int maxProximityCharsSize, const int keyboardWidth,
+ const int keyboardHeight, const int gridWidth, const int gridHeight,
+ const uint32_t *proximityCharsArray)
+ : MAX_PROXIMITY_CHARS_SIZE(maxProximityCharsSize), KEYBOARD_WIDTH(keyboardWidth),
+ KEYBOARD_HEIGHT(keyboardHeight), GRID_WIDTH(gridWidth), GRID_HEIGHT(gridHeight),
+ CELL_WIDTH((keyboardWidth + gridWidth - 1) / gridWidth),
+ CELL_HEIGHT((keyboardHeight + gridHeight - 1) / gridHeight) {
+ const int len = GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE;
+ mProximityCharsArray = new uint32_t[len];
+ if (DEBUG_PROXIMITY_INFO) {
+ LOGI("Create proximity info array %d", len);
+ }
+ memcpy(mProximityCharsArray, proximityCharsArray, len * sizeof(mProximityCharsArray[0]));
}
ProximityInfo::~ProximityInfo() {
delete[] mProximityCharsArray;
}
+
+inline int ProximityInfo::getStartIndexFromCoordinates(const int x, const int y) const {
+ return (y / CELL_HEIGHT) * GRID_WIDTH + (x / CELL_WIDTH)
+ * MAX_PROXIMITY_CHARS_SIZE;
+}
+
+bool ProximityInfo::hasSpaceProximity(const int x, const int y) const {
+ const int startIndex = getStartIndexFromCoordinates(x, y);
+ if (DEBUG_PROXIMITY_INFO) {
+ LOGI("hasSpaceProximity: index %d", startIndex);
+ }
+ for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
+ if (DEBUG_PROXIMITY_INFO) {
+ LOGI("Index: %d", mProximityCharsArray[startIndex + i]);
+ }
+ if (mProximityCharsArray[startIndex + i] == KEYCODE_SPACE) {
+ return true;
+ }
+ }
+ return false;
}
+} // namespace latinime
diff --git a/native/src/proximity_info.h b/native/src/proximity_info.h
index 54e995059..0f1201866 100644
--- a/native/src/proximity_info.h
+++ b/native/src/proximity_info.h
@@ -25,15 +25,20 @@ namespace latinime {
class ProximityInfo {
public:
- ProximityInfo(int maxProximityCharsSize, int displayWidth, int displayHeight, int gridWidth,
- int gridHeight, uint32_t const *proximityCharsArray);
+ ProximityInfo(const int maxProximityCharsSize, const int keyboardWidth,
+ const int keybaordHeight, const int gridWidth, const int gridHeight,
+ const uint32_t *proximityCharsArray);
~ProximityInfo();
+ bool hasSpaceProximity(const int x, const int y) const;
private:
- const int MAX_PROXIMITY_CHARS_SIZE;
- const int DISPLAY_WIDTH;
- const int DISPLAY_HEIGHT;
+ int getStartIndexFromCoordinates(const int x, const int y) const;
+ const int CELL_WIDTH;
+ const int CELL_HEIGHT;
+ const int KEYBOARD_WIDTH;
+ const int KEYBOARD_HEIGHT;
const int GRID_WIDTH;
const int GRID_HEIGHT;
+ const int MAX_PROXIMITY_CHARS_SIZE;
uint32_t *mProximityCharsArray;
};
}; // namespace latinime
diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp
index b82910a40..274e1f6d3 100644
--- a/native/src/unigram_dictionary.cpp
+++ b/native/src/unigram_dictionary.cpp
@@ -142,7 +142,7 @@ int UnigramDictionary::getSuggestions(const ProximityInfo *proximityInfo, const
outWords, frequencies);
}
- PROF_START(6);
+ PROF_START(20);
// Get the word count
int suggestedWordsCount = 0;
while (suggestedWordsCount < MAX_WORDS && mFrequencies[suggestedWordsCount] > 0) {
@@ -158,7 +158,7 @@ int UnigramDictionary::getSuggestions(const ProximityInfo *proximityInfo, const
}
}
}
- PROF_END(6);
+ PROF_END(20);
PROF_CLOSE;
return suggestedWordsCount;
}
@@ -172,12 +172,6 @@ void UnigramDictionary::getWordSuggestions(const ProximityInfo *proximityInfo,
initSuggestions(codes, codesSize, outWords, frequencies);
if (DEBUG_DICT) assert(codesSize == mInputLength);
- if (DEBUG_PROXIMITY_INFO) {
- for (int i = 0; i < codesSize; ++i) {
- LOGI("Input[%d] x = %d, y = %d", i, xcoordinates[i], ycoordinates[i]);
- }
- }
-
const int MAX_DEPTH = min(mInputLength * MAX_DEPTH_MULTIPLIER, MAX_WORD_LENGTH);
PROF_END(0);
@@ -227,6 +221,25 @@ void UnigramDictionary::getWordSuggestions(const ProximityInfo *proximityInfo,
}
}
PROF_END(5);
+
+ PROF_START(6);
+ if (SUGGEST_WORDS_WITH_SPACE_PROXIMITY) {
+ // The first and last "mistyped spaces" are taken care of by excessive character handling
+ for (int i = 1; i < codesSize - 1; ++i) {
+ if (DEBUG_DICT) LOGI("--- Suggest words with proximity space %d", i);
+ const int x = xcoordinates[i];
+ const int y = ycoordinates[i];
+ if (DEBUG_PROXIMITY_INFO)
+ LOGI("Input[%d] x = %d, y = %d, has space proximity = %d",
+ i, x, y, proximityInfo->hasSpaceProximity(x, y));
+
+ if (proximityInfo->hasSpaceProximity(x, y)) {
+ getMistypedSpaceWords(mInputLength, i);
+ }
+
+ }
+ }
+ PROF_END(6);
}
void UnigramDictionary::initSuggestions(const int *codes, const int codesSize,
@@ -387,27 +400,31 @@ inline static void multiplyRate(const int rate, int *freq) {
}
}
-bool UnigramDictionary::getMissingSpaceWords(const int inputLength, const int missingSpacePos) {
- if (missingSpacePos <= 0 || missingSpacePos >= inputLength
- || inputLength >= MAX_WORD_LENGTH) return false;
- const int newWordLength = inputLength + 1;
+bool UnigramDictionary::getSplitTwoWordsSuggestion(const int inputLength,
+ const int firstWordStartPos, const int firstWordLength, const int secondWordStartPos,
+ const int secondWordLength) {
+ if (inputLength >= MAX_WORD_LENGTH) return false;
+ if (0 >= firstWordLength || 0 >= secondWordLength || firstWordStartPos >= secondWordStartPos
+ || firstWordStartPos < 0 || secondWordStartPos >= inputLength)
+ return false;
+ const int newWordLength = firstWordLength + secondWordLength + 1;
// Allocating variable length array on stack
unsigned short word[newWordLength];
- const int firstFreq = getBestWordFreq(0, missingSpacePos, mWord);
+ const int firstFreq = getBestWordFreq(firstWordStartPos, firstWordLength, mWord);
if (DEBUG_DICT) LOGI("First freq: %d", firstFreq);
if (firstFreq <= 0) return false;
- for (int i = 0; i < missingSpacePos; ++i) {
+ for (int i = 0; i < firstWordLength; ++i) {
word[i] = mWord[i];
}
- const int secondFreq = getBestWordFreq(missingSpacePos, inputLength - missingSpacePos, mWord);
+ const int secondFreq = getBestWordFreq(secondWordStartPos, secondWordLength, mWord);
if (DEBUG_DICT) LOGI("Second freq: %d", secondFreq);
if (secondFreq <= 0) return false;
- word[missingSpacePos] = SPACE;
- for (int i = (missingSpacePos + 1); i < newWordLength; ++i) {
- word[i] = mWord[i - missingSpacePos - 1];
+ word[firstWordLength] = SPACE;
+ for (int i = (firstWordLength + 1); i < newWordLength; ++i) {
+ word[i] = mWord[i - firstWordLength - 1];
}
int pairFreq = ((firstFreq + secondFreq) / 2);
@@ -417,6 +434,17 @@ bool UnigramDictionary::getMissingSpaceWords(const int inputLength, const int mi
return true;
}
+bool UnigramDictionary::getMissingSpaceWords(const int inputLength, const int missingSpacePos) {
+ return getSplitTwoWordsSuggestion(
+ inputLength, 0, missingSpacePos, missingSpacePos, inputLength - missingSpacePos);
+}
+
+bool UnigramDictionary::getMistypedSpaceWords(const int inputLength, const int spaceProximityPos) {
+ return getSplitTwoWordsSuggestion(
+ inputLength, 0, spaceProximityPos, spaceProximityPos + 1,
+ inputLength - spaceProximityPos - 1);
+}
+
// Keep this for comparing spec to new getWords
void UnigramDictionary::getWordsOld(const int initialPos, const int inputLength, const int skipPos,
const int excessivePos, const int transposedPos,int *nextLetters,
diff --git a/native/src/unigram_dictionary.h b/native/src/unigram_dictionary.h
index 8a4b40e0c..7359481a8 100644
--- a/native/src/unigram_dictionary.h
+++ b/native/src/unigram_dictionary.h
@@ -64,7 +64,11 @@ private:
const bool traverseAllNodes, const int snr, const int inputIndex, const int diffs,
const int skipPos, const int excessivePos, const int transposedPos, int *nextLetters,
const int nextLettersSize);
+ bool getSplitTwoWordsSuggestion(const int inputLength,
+ const int firstWordStartPos, const int firstWordLength,
+ const int secondWordStartPos, const int secondWordLength);
bool getMissingSpaceWords(const int inputLength, const int missingSpacePos);
+ bool getMistypedSpaceWords(const int inputLength, const int spaceProximityPos);
// Keep getWordsOld for comparing performance between getWords and getWordsOld
void getWordsOld(const int initialPos, const int inputLength, const int skipPos,
const int excessivePos, const int transposedPos, int *nextLetters,