diff options
Diffstat (limited to 'native/jni/src')
-rw-r--r-- | native/jni/src/correction.cpp | 10 | ||||
-rw-r--r-- | native/jni/src/correction.h | 2 | ||||
-rw-r--r-- | native/jni/src/defines.h | 10 | ||||
-rw-r--r-- | native/jni/src/unigram_dictionary.cpp | 13 | ||||
-rw-r--r-- | native/jni/src/words_priority_queue.h | 79 |
5 files changed, 75 insertions, 39 deletions
diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp index a1f812909..5ae34cd02 100644 --- a/native/jni/src/correction.cpp +++ b/native/jni/src/correction.cpp @@ -1113,7 +1113,7 @@ int Correction::RankingAlgorithm::editDistance(const unsigned short* before, // So, we can normalize original score by dividing pow(2, min(b.l(),a.l())) * 255 * 2. /* static */ -double Correction::RankingAlgorithm::calcNormalizedScore(const unsigned short* before, +float Correction::RankingAlgorithm::calcNormalizedScore(const unsigned short* before, const int beforeLength, const unsigned short* after, const int afterLength, const int score) { if (0 == beforeLength || 0 == afterLength) { @@ -1131,14 +1131,14 @@ double Correction::RankingAlgorithm::calcNormalizedScore(const unsigned short* b return 0; } - const double maxScore = score >= S_INT_MAX ? S_INT_MAX : MAX_INITIAL_SCORE - * pow((double)TYPED_LETTER_MULTIPLIER, - (double)min(beforeLength, afterLength - spaceCount)) * FULL_WORD_MULTIPLIER; + const float maxScore = score >= S_INT_MAX ? S_INT_MAX : MAX_INITIAL_SCORE + * pow((float)TYPED_LETTER_MULTIPLIER, + (float)min(beforeLength, afterLength - spaceCount)) * FULL_WORD_MULTIPLIER; // add a weight based on edit distance. // distance <= max(afterLength, beforeLength) == afterLength, // so, 0 <= distance / afterLength <= 1 - const double weight = 1.0 - (double) distance / afterLength; + const float weight = 1.0 - (float) distance / afterLength; return (score / maxScore) * weight; } diff --git a/native/jni/src/correction.h b/native/jni/src/correction.h index 1b4e4bf4e..1ac4b8782 100644 --- a/native/jni/src/correction.h +++ b/native/jni/src/correction.h @@ -162,7 +162,7 @@ class Correction { static int calcFreqForSplitMultipleWords(const int *freqArray, const int *wordLengthArray, const int wordCount, const Correction* correction, const bool isSpaceProximity, const unsigned short *word); - static double calcNormalizedScore(const unsigned short* before, const int beforeLength, + static float calcNormalizedScore(const unsigned short* before, const int beforeLength, const unsigned short* after, const int afterLength, const int score); static int editDistance(const unsigned short* before, const int beforeLength, const unsigned short* after, const int afterLength); diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h index cb3dbb115..c6ad66abe 100644 --- a/native/jni/src/defines.h +++ b/native/jni/src/defines.h @@ -46,8 +46,8 @@ static inline void dumpWord(const unsigned short* word, const int length) { #include <time.h> #define PROF_BUF_SIZE 100 -static double profile_buf[PROF_BUF_SIZE]; -static double profile_old[PROF_BUF_SIZE]; +static float profile_buf[PROF_BUF_SIZE]; +static float profile_old[PROF_BUF_SIZE]; static unsigned int profile_counter[PROF_BUF_SIZE]; #define PROF_RESET prof_reset() @@ -74,8 +74,8 @@ static inline void prof_out(void) { AKLOGI("Error: You must call PROF_OPEN before PROF_CLOSE."); } AKLOGI("Total time is %6.3f ms.", - profile_buf[PROF_BUF_SIZE - 1] * 1000 / (double)CLOCKS_PER_SEC); - double all = 0; + profile_buf[PROF_BUF_SIZE - 1] * 1000 / (float)CLOCKS_PER_SEC); + float all = 0; for (int i = 0; i < PROF_BUF_SIZE - 1; ++i) { all += profile_buf[i]; } @@ -84,7 +84,7 @@ static inline void prof_out(void) { if (profile_buf[i] != 0) { AKLOGI("(%d): Used %4.2f%%, %8.4f ms. Called %d times.", i, (profile_buf[i] * 100 / all), - profile_buf[i] * 1000 / (double)CLOCKS_PER_SEC, profile_counter[i]); + profile_buf[i] * 1000 / (float)CLOCKS_PER_SEC, profile_counter[i]); } } } diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp index 9234b1b52..ee8c49703 100644 --- a/native/jni/src/unigram_dictionary.cpp +++ b/native/jni/src/unigram_dictionary.cpp @@ -202,16 +202,17 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo, PROF_START(20); if (DEBUG_DICT) { - double ns = queuePool->getMasterQueue()->getHighestNormalizedScore( + float ns = queuePool->getMasterQueue()->getHighestNormalizedScore( proximityInfo->getPrimaryInputWord(), codesSize, 0, 0, 0); ns += 0; AKLOGI("Max normalized score = %f", ns); } const int suggestedWordsCount = - queuePool->getMasterQueue()->outputSuggestions(frequencies, outWords); + queuePool->getMasterQueue()->outputSuggestions( + proximityInfo->getPrimaryInputWord(), codesSize, frequencies, outWords); if (DEBUG_DICT) { - double ns = queuePool->getMasterQueue()->getHighestNormalizedScore( + float ns = queuePool->getMasterQueue()->getHighestNormalizedScore( proximityInfo->getPrimaryInputWord(), codesSize, 0, 0, 0); ns += 0; AKLOGI("Returning %d words", suggestedWordsCount); @@ -254,7 +255,7 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo, bool hasAutoCorrectionCandidate = false; WordsPriorityQueue* masterQueue = queuePool->getMasterQueue(); if (masterQueue->size() > 0) { - double nsForMaster = masterQueue->getHighestNormalizedScore( + float nsForMaster = masterQueue->getHighestNormalizedScore( proximityInfo->getPrimaryInputWord(), inputLength, 0, 0, 0); hasAutoCorrectionCandidate = (nsForMaster > START_TWO_WORDS_CORRECTION_THRESHOLD); } @@ -283,7 +284,7 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo, const int score = sw->mScore; const unsigned short* word = sw->mWord; const int wordLength = sw->mWordLength; - double ns = Correction::RankingAlgorithm::calcNormalizedScore( + float ns = Correction::RankingAlgorithm::calcNormalizedScore( proximityInfo->getPrimaryInputWord(), i, word, wordLength, score); ns += 0; AKLOGI("--- TOP SUB WORDS for %d --- %d %f [%d]", i, score, ns, @@ -451,7 +452,7 @@ bool UnigramDictionary::getSubStringSuggestion( return false; } int score = 0; - const double ns = queue->getHighestNormalizedScore( + const float ns = queue->getHighestNormalizedScore( proximityInfo->getPrimaryInputWord(), inputWordLength, &tempOutputWord, &score, &nextWordLength); if (DEBUG_DICT) { diff --git a/native/jni/src/words_priority_queue.h b/native/jni/src/words_priority_queue.h index 249962eec..7629251d6 100644 --- a/native/jni/src/words_priority_queue.h +++ b/native/jni/src/words_priority_queue.h @@ -92,10 +92,12 @@ class WordsPriorityQueue { return sw; } - int outputSuggestions(int *frequencies, unsigned short *outputChars) { + int outputSuggestions(const unsigned short* before, const int beforeLength, + int *frequencies, unsigned short *outputChars) { mHighestSuggestedWord = 0; const unsigned int size = min( MAX_WORDS, static_cast<unsigned int>(mSuggestions.size())); + SuggestedWord* swBuffer[size]; int index = size - 1; while (!mSuggestions.empty() && index >= 0) { SuggestedWord* sw = mSuggestions.top(); @@ -103,17 +105,45 @@ class WordsPriorityQueue { AKLOGI("dump word. %d", sw->mScore); DUMP_WORD(sw->mWord, sw->mWordLength); } + swBuffer[index] = sw; + mSuggestions.pop(); + --index; + } + if (size >= 2) { + SuggestedWord* nsMaxSw = 0; + unsigned int maxIndex = 0; + float maxNs = 0; + for (unsigned int i = 0; i < size; ++i) { + SuggestedWord* tempSw = swBuffer[i]; + if (!tempSw) { + continue; + } + const float tempNs = getNormalizedScore(tempSw, before, beforeLength, 0, 0, 0); + if (tempNs >= maxNs) { + maxNs = tempNs; + maxIndex = i; + nsMaxSw = tempSw; + } + } + if (maxIndex > 0 && nsMaxSw) { + memmove(&swBuffer[1], &swBuffer[0], maxIndex * sizeof(SuggestedWord*)); + swBuffer[0] = nsMaxSw; + } + } + for (unsigned int i = 0; i < size; ++i) { + SuggestedWord* sw = swBuffer[i]; + if (!sw) { + AKLOGE("SuggestedWord is null %d", i); + continue; + } const unsigned int wordLength = sw->mWordLength; - char* targetAdr = (char*) outputChars - + (index) * MAX_WORD_LENGTH * sizeof(short); - frequencies[index] = sw->mScore; + char* targetAdr = (char*) outputChars + i * MAX_WORD_LENGTH * sizeof(short); + frequencies[i] = sw->mScore; memcpy(targetAdr, sw->mWord, (wordLength) * sizeof(short)); if (wordLength < MAX_WORD_LENGTH) { ((unsigned short*) targetAdr)[wordLength] = 0; } sw->mUsed = false; - mSuggestions.pop(); - --index; } return size; } @@ -142,26 +172,13 @@ class WordsPriorityQueue { DUMP_WORD(mHighestSuggestedWord->mWord, mHighestSuggestedWord->mWordLength); } - double getHighestNormalizedScore(const unsigned short* before, const int beforeLength, + float getHighestNormalizedScore(const unsigned short* before, const int beforeLength, unsigned short** outWord, int *outScore, int *outLength) { if (!mHighestSuggestedWord) { return 0.0; } - SuggestedWord* sw = mHighestSuggestedWord; - const int score = sw->mScore; - unsigned short* word = sw->mWord; - const int wordLength = sw->mWordLength; - if (outScore) { - *outScore = score; - } - if (outWord) { - *outWord = word; - } - if (outLength) { - *outLength = wordLength; - } - return Correction::RankingAlgorithm::calcNormalizedScore( - before, beforeLength, word, wordLength, score); + return getNormalizedScore( + mHighestSuggestedWord, before, beforeLength, outWord, outScore, outLength); } private: @@ -182,6 +199,24 @@ class WordsPriorityQueue { return 0; } + static float getNormalizedScore(SuggestedWord* sw, const unsigned short* before, + const int beforeLength, unsigned short** outWord, int *outScore, int *outLength) { + const int score = sw->mScore; + unsigned short* word = sw->mWord; + const int wordLength = sw->mWordLength; + if (outScore) { + *outScore = score; + } + if (outWord) { + *outWord = word; + } + if (outLength) { + *outLength = wordLength; + } + return Correction::RankingAlgorithm::calcNormalizedScore( + before, beforeLength, word, wordLength, score); + } + typedef std::priority_queue<SuggestedWord*, std::vector<SuggestedWord*>, wordComparator> Suggestions; Suggestions mSuggestions; |