1e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi/* 2e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * Copyright (C) 2014 The Android Open Source Project 3e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * 4e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * Licensed under the Apache License, Version 2.0 (the "License"); 5e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * you may not use this file except in compliance with the License. 6e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * You may obtain a copy of the License at 7e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * 8e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * http://www.apache.org/licenses/LICENSE-2.0 9e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * 10e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * Unless required by applicable law or agreed to in writing, software 11e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * distributed under the License is distributed on an "AS IS" BASIS, 12e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * See the License for the specific language governing permissions and 14e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi * limitations under the License. 15e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi */ 16e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi 17e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi#include "suggest/core/result/suggestion_results.h" 18e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi 19d2f7cd28aefb71f3f340f1a8572e5477e5f5dfb3Keisuke Kuroyanagi#include "utils/jni_data_utils.h" 20d2f7cd28aefb71f3f340f1a8572e5477e5f5dfb3Keisuke Kuroyanagi 21e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanaginamespace latinime { 22e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi 23e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagivoid SuggestionResults::outputSuggestions(JNIEnv *env, jintArray outSuggestionCount, 24e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi jintArray outputCodePointsArray, jintArray outScoresArray, jintArray outSpaceIndicesArray, 25de2b312c6d00509a313c076d0be37eea5c2d41f3Keisuke Kuroyanagi jintArray outTypesArray, jintArray outAutoCommitFirstWordConfidenceArray, 266da9b21191dc7d6049d96945366ec7e605e716e6Jean Chalard jfloatArray outWeightOfLangModelVsSpatialModel) { 27e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi int outputIndex = 0; 28e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi while (!mSuggestedWords.empty()) { 29e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi const SuggestedWord &suggestedWord = mSuggestedWords.top(); 30e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi suggestedWord.getCodePointCount(); 31e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi const int start = outputIndex * MAX_WORD_LENGTH; 32d2f7cd28aefb71f3f340f1a8572e5477e5f5dfb3Keisuke Kuroyanagi JniDataUtils::outputCodePoints(env, outputCodePointsArray, start, 33d2f7cd28aefb71f3f340f1a8572e5477e5f5dfb3Keisuke Kuroyanagi MAX_WORD_LENGTH /* maxLength */, suggestedWord.getCodePoint(), 34d2f7cd28aefb71f3f340f1a8572e5477e5f5dfb3Keisuke Kuroyanagi suggestedWord.getCodePointCount(), true /* needsNullTermination */); 35304a71d171fc1041f5c19b1f05fbe329c6a3ed3fKeisuke Kuroyanagi JniDataUtils::putIntToArray(env, outScoresArray, outputIndex, suggestedWord.getScore()); 36304a71d171fc1041f5c19b1f05fbe329c6a3ed3fKeisuke Kuroyanagi JniDataUtils::putIntToArray(env, outSpaceIndicesArray, outputIndex, 37304a71d171fc1041f5c19b1f05fbe329c6a3ed3fKeisuke Kuroyanagi suggestedWord.getIndexToPartialCommit()); 38304a71d171fc1041f5c19b1f05fbe329c6a3ed3fKeisuke Kuroyanagi JniDataUtils::putIntToArray(env, outTypesArray, outputIndex, suggestedWord.getType()); 39e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi if (mSuggestedWords.size() == 1) { 40304a71d171fc1041f5c19b1f05fbe329c6a3ed3fKeisuke Kuroyanagi JniDataUtils::putIntToArray(env, outAutoCommitFirstWordConfidenceArray, 0 /* index */, 41304a71d171fc1041f5c19b1f05fbe329c6a3ed3fKeisuke Kuroyanagi suggestedWord.getAutoCommitFirstWordConfidence()); 42e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi } 43e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi ++outputIndex; 44e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi mSuggestedWords.pop(); 45e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi } 46304a71d171fc1041f5c19b1f05fbe329c6a3ed3fKeisuke Kuroyanagi JniDataUtils::putIntToArray(env, outSuggestionCount, 0 /* index */, outputIndex); 476da9b21191dc7d6049d96945366ec7e605e716e6Jean Chalard JniDataUtils::putFloatToArray(env, outWeightOfLangModelVsSpatialModel, 0 /* index */, 486da9b21191dc7d6049d96945366ec7e605e716e6Jean Chalard mWeightOfLangModelVsSpatialModel); 49e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi} 50e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi 51e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagivoid SuggestionResults::addPrediction(const int *const codePoints, const int codePointCount, 52e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi const int probability) { 53d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi if (probability == NOT_A_PROBABILITY) { 54e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi // Invalid word. 55e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi return; 56e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi } 57d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi addSuggestion(codePoints, codePointCount, probability, Dictionary::KIND_PREDICTION, 58d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi NOT_AN_INDEX, NOT_A_FIRST_WORD_CONFIDENCE); 59d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi} 60d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi 61d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagivoid SuggestionResults::addSuggestion(const int *const codePoints, const int codePointCount, 62d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi const int score, const int type, const int indexToPartialCommit, 63d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi const int autocimmitFirstWordConfindence) { 64d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi if (codePointCount <= 0 || codePointCount > MAX_WORD_LENGTH) { 65d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi // Invalid word. 66d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi AKLOGE("Invalid word is added to the suggestion results. codePointCount: %d", 67d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi codePointCount); 68d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi return; 69d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi } 70e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi if (getSuggestionCount() >= mMaxSuggestionCount) { 71e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi const SuggestedWord &mWorstSuggestion = mSuggestedWords.top(); 72e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi if (score > mWorstSuggestion.getScore() || (score == mWorstSuggestion.getScore() 73e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi && codePointCount < mWorstSuggestion.getCodePointCount())) { 74e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi mSuggestedWords.pop(); 75e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi } else { 76e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi return; 77e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi } 78e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi } 79d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi mSuggestedWords.push(SuggestedWord(codePoints, codePointCount, score, type, 80d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi indexToPartialCommit, autocimmitFirstWordConfindence)); 81d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi} 82d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi 83d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagivoid SuggestionResults::getSortedScores(int *const outScores) const { 84d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi auto copyOfSuggestedWords = mSuggestedWords; 85d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi while (!copyOfSuggestedWords.empty()) { 86d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi const SuggestedWord &suggestedWord = copyOfSuggestedWords.top(); 87d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi outScores[copyOfSuggestedWords.size() - 1] = suggestedWord.getScore(); 88d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi copyOfSuggestedWords.pop(); 89d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi } 90d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi} 91d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi 92d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagivoid SuggestionResults::dumpSuggestions() const { 936da9b21191dc7d6049d96945366ec7e605e716e6Jean Chalard AKLOGE("weight of language model vs spatial model: %f", mWeightOfLangModelVsSpatialModel); 94d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi std::vector<SuggestedWord> suggestedWords; 95d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi auto copyOfSuggestedWords = mSuggestedWords; 96d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi while (!copyOfSuggestedWords.empty()) { 97d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi suggestedWords.push_back(copyOfSuggestedWords.top()); 98d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi copyOfSuggestedWords.pop(); 99d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi } 100d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi int index = 0; 101d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi for (auto it = suggestedWords.rbegin(); it != suggestedWords.rend(); ++it) { 102d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi DUMP_SUGGESTION(it->getCodePoint(), it->getCodePointCount(), index, it->getScore()); 103d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi index++; 104d73edf23aca59e6a0a83a79cf24db3850ef473ffKeisuke Kuroyanagi } 105e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi} 106e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi 107e137ec0a91cf93b0a99fd1e1556ee835d026f731Keisuke Kuroyanagi} // namespace latinime 108