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