1a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka/* 2a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * Copyright (C) 2012 The Android Open Source Project 3a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * 4a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * Licensed under the Apache License, Version 2.0 (the "License"); 5a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * you may not use this file except in compliance with the License. 6a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * You may obtain a copy of the License at 7a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * 8a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * http://www.apache.org/licenses/LICENSE-2.0 9a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * 10a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * Unless required by applicable law or agreed to in writing, software 11a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * distributed under the License is distributed on an "AS IS" BASIS, 12a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * See the License for the specific language governing permissions and 14a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * limitations under the License. 15a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka */ 16a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 17a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka#ifndef LATINIME_TYPING_WEIGHTING_H 18a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka#define LATINIME_TYPING_WEIGHTING_H 19a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 20a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka#include "defines.h" 21b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa#include "suggest/core/dicnode/dic_node_utils.h" 222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/core/dictionary/error_type_utils.h" 2329432f843a8cd6ffb2be286104964592e80d77c9Ken Wakasa#include "suggest/core/layout/touch_position_correction_utils.h" 24b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa#include "suggest/core/policy/weighting.h" 25b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa#include "suggest/core/session/dic_traverse_session.h" 26b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa#include "suggest/policyimpl/typing/scoring_params.h" 27addea83bad5751308fef508d79c6989b8872f050Ken Wakasa#include "utils/char_utils.h" 28a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 29a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataokanamespace latinime { 30a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 31a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataokaclass DicNode; 32a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataokastruct DicNode_InputStateG; 339559dd2e30de288a9ff7069bfc59f8500b949a88Tom Ouyangclass MultiBigramMap; 34a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 35a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataokaclass TypingWeighting : public Weighting { 36a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka public: 37a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka static const TypingWeighting *getInstance() { return &sInstance; } 38a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 39a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka protected: 40866a6ced571a24f0f1b927aeccad7a1969da23b7Ken Wakasa float getTerminalSpatialCost(const DicTraverseSession *const traverseSession, 41866a6ced571a24f0f1b927aeccad7a1969da23b7Ken Wakasa const DicNode *const dicNode) const { 42a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka float cost = 0.0f; 43a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka if (dicNode->hasMultipleWords()) { 44a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka cost += ScoringParams::HAS_MULTI_WORD_TERMINAL_COST; 45a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 46a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka if (dicNode->getProximityCorrectionCount() > 0) { 47a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka cost += ScoringParams::HAS_PROXIMITY_TERMINAL_COST; 48a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 49a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka if (dicNode->getEditCorrectionCount() > 0) { 50a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka cost += ScoringParams::HAS_EDIT_CORRECTION_TERMINAL_COST; 51a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 52a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return cost; 53a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 54a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 55a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka float getOmissionCost(const DicNode *const parentDicNode, const DicNode *const dicNode) const { 5660a169f0c34bf0da89c420d99bfff5c2556f3fbfKeisuke Kuroynagi const bool isZeroCostOmission = parentDicNode->isZeroCostOmission(); 5714dd663fe51079e74c8527d1452d5aa68fecc4e8Keisuke Kuroyanagi const bool isIntentionalOmission = parentDicNode->canBeIntentionalOmission(); 5860a169f0c34bf0da89c420d99bfff5c2556f3fbfKeisuke Kuroynagi const bool sameCodePoint = dicNode->isSameNodeCodePoint(parentDicNode); 59a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka // If the traversal omitted the first letter then the dicNode should now be on the second. 6009858cbde49c086dd1d4d3050b57f0ea1774158bKeisuke Kuroynagi const bool isFirstLetterOmission = dicNode->getNodeCodePointCount() == 2; 6160a169f0c34bf0da89c420d99bfff5c2556f3fbfKeisuke Kuroynagi float cost = 0.0f; 6260a169f0c34bf0da89c420d99bfff5c2556f3fbfKeisuke Kuroynagi if (isZeroCostOmission) { 6360a169f0c34bf0da89c420d99bfff5c2556f3fbfKeisuke Kuroynagi cost = 0.0f; 6414dd663fe51079e74c8527d1452d5aa68fecc4e8Keisuke Kuroyanagi } else if (isIntentionalOmission) { 6514dd663fe51079e74c8527d1452d5aa68fecc4e8Keisuke Kuroyanagi cost = ScoringParams::INTENTIONAL_OMISSION_COST; 6660a169f0c34bf0da89c420d99bfff5c2556f3fbfKeisuke Kuroynagi } else if (isFirstLetterOmission) { 67a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka cost = ScoringParams::OMISSION_COST_FIRST_CHAR; 68a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } else { 69a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka cost = sameCodePoint ? ScoringParams::OMISSION_COST_SAME_CHAR 70a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka : ScoringParams::OMISSION_COST; 71a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 72a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return cost; 73a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 74a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 75866a6ced571a24f0f1b927aeccad7a1969da23b7Ken Wakasa float getMatchedCost(const DicTraverseSession *const traverseSession, 76866a6ced571a24f0f1b927aeccad7a1969da23b7Ken Wakasa const DicNode *const dicNode, DicNode_InputStateG *inputStateG) const { 77a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int pointIndex = dicNode->getInputIndex(0); 78837f46dcb35a8f42a6bd5bc5fc6395d7386acb81Satoshi Kataoka const float normalizedSquaredLength = traverseSession->getProximityInfoState(0) 79e639d7346c59b21fffc6b6e1e05022bb6b84fb74Keisuke Kuroyanagi ->getPointToKeyLength(pointIndex, 80e639d7346c59b21fffc6b6e1e05022bb6b84fb74Keisuke Kuroyanagi CharUtils::toBaseLowerCase(dicNode->getNodeCodePoint())); 8129432f843a8cd6ffb2be286104964592e80d77c9Ken Wakasa const float normalizedDistance = TouchPositionCorrectionUtils::getSweetSpotFactor( 82837f46dcb35a8f42a6bd5bc5fc6395d7386acb81Satoshi Kataoka traverseSession->isTouchPositionCorrectionEnabled(), normalizedSquaredLength); 83837f46dcb35a8f42a6bd5bc5fc6395d7386acb81Satoshi Kataoka const float weightedDistance = ScoringParams::DISTANCE_WEIGHT_LENGTH * normalizedDistance; 84837f46dcb35a8f42a6bd5bc5fc6395d7386acb81Satoshi Kataoka 85a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const bool isFirstChar = pointIndex == 0; 86a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const bool isProximity = isProximityDicNode(traverseSession, dicNode); 87cb4a7c1d87106c5ac8c13e752b1ceaf585448538Keisuke Kuroynagi float cost = isProximity ? (isFirstChar ? ScoringParams::FIRST_CHAR_PROXIMITY_COST 88a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka : ScoringParams::PROXIMITY_COST) : 0.0f; 89cb4a7c1d87106c5ac8c13e752b1ceaf585448538Keisuke Kuroynagi if (isProximity && dicNode->getProximityCorrectionCount() == 0) { 90cb4a7c1d87106c5ac8c13e752b1ceaf585448538Keisuke Kuroynagi cost += ScoringParams::FIRST_PROXIMITY_COST; 91cb4a7c1d87106c5ac8c13e752b1ceaf585448538Keisuke Kuroynagi } 9209858cbde49c086dd1d4d3050b57f0ea1774158bKeisuke Kuroynagi if (dicNode->getNodeCodePointCount() == 2) { 93a107dcaeb6302981974bab8284f6b7943673cf11Keisuke Kuroynagi // At the second character of the current word, we check if the first char is uppercase 94a107dcaeb6302981974bab8284f6b7943673cf11Keisuke Kuroynagi // and the word is a second or later word of a multiple word suggestion. We demote it 95a107dcaeb6302981974bab8284f6b7943673cf11Keisuke Kuroynagi // if so. 96a107dcaeb6302981974bab8284f6b7943673cf11Keisuke Kuroynagi const bool isSecondOrLaterWordFirstCharUppercase = 97a107dcaeb6302981974bab8284f6b7943673cf11Keisuke Kuroynagi dicNode->hasMultipleWords() && dicNode->isFirstCharUppercase(); 98a107dcaeb6302981974bab8284f6b7943673cf11Keisuke Kuroynagi if (isSecondOrLaterWordFirstCharUppercase) { 99a107dcaeb6302981974bab8284f6b7943673cf11Keisuke Kuroynagi cost += ScoringParams::COST_SECOND_OR_LATER_WORD_FIRST_CHAR_UPPERCASE; 100a107dcaeb6302981974bab8284f6b7943673cf11Keisuke Kuroynagi } 101a107dcaeb6302981974bab8284f6b7943673cf11Keisuke Kuroynagi } 102a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return weightedDistance + cost; 103a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 104a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 105866a6ced571a24f0f1b927aeccad7a1969da23b7Ken Wakasa bool isProximityDicNode(const DicTraverseSession *const traverseSession, 106866a6ced571a24f0f1b927aeccad7a1969da23b7Ken Wakasa const DicNode *const dicNode) const { 107a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int pointIndex = dicNode->getInputIndex(0); 108464d3ba43257da34ab165da8ba0af11e928aae5cKen Wakasa const int primaryCodePoint = CharUtils::toBaseLowerCase( 109a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka traverseSession->getProximityInfoState(0)->getPrimaryCodePointAt(pointIndex)); 110464d3ba43257da34ab165da8ba0af11e928aae5cKen Wakasa const int dicNodeChar = CharUtils::toBaseLowerCase(dicNode->getNodeCodePoint()); 111a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return primaryCodePoint != dicNodeChar; 112a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 113a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 114866a6ced571a24f0f1b927aeccad7a1969da23b7Ken Wakasa float getTranspositionCost(const DicTraverseSession *const traverseSession, 115866a6ced571a24f0f1b927aeccad7a1969da23b7Ken Wakasa const DicNode *const parentDicNode, const DicNode *const dicNode) const { 116a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int16_t parentPointIndex = parentDicNode->getInputIndex(0); 117a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int prevCodePoint = parentDicNode->getNodeCodePoint(); 118a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const float distance1 = traverseSession->getProximityInfoState(0)->getPointToKeyLength( 119e639d7346c59b21fffc6b6e1e05022bb6b84fb74Keisuke Kuroyanagi parentPointIndex + 1, CharUtils::toBaseLowerCase(prevCodePoint)); 120a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int codePoint = dicNode->getNodeCodePoint(); 121a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const float distance2 = traverseSession->getProximityInfoState(0)->getPointToKeyLength( 122e639d7346c59b21fffc6b6e1e05022bb6b84fb74Keisuke Kuroyanagi parentPointIndex, CharUtils::toBaseLowerCase(codePoint)); 123a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const float distance = distance1 + distance2; 124a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const float weightedLengthDistance = 125a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka distance * ScoringParams::DISTANCE_WEIGHT_LENGTH; 126a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return ScoringParams::TRANSPOSITION_COST + weightedLengthDistance; 127a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 128a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 129866a6ced571a24f0f1b927aeccad7a1969da23b7Ken Wakasa float getInsertionCost(const DicTraverseSession *const traverseSession, 130a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const DicNode *const parentDicNode, const DicNode *const dicNode) const { 13124706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi const int16_t insertedPointIndex = parentDicNode->getInputIndex(0); 13224706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi const int prevCodePoint = traverseSession->getProximityInfoState(0)->getPrimaryCodePointAt( 13324706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi insertedPointIndex); 134a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int currentCodePoint = dicNode->getNodeCodePoint(); 135a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const bool sameCodePoint = prevCodePoint == currentCodePoint; 13624706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi const bool existsAdjacentProximityChars = traverseSession->getProximityInfoState(0) 13724706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi ->existsAdjacentProximityChars(insertedPointIndex); 138a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const float dist = traverseSession->getProximityInfoState(0)->getPointToKeyLength( 139e639d7346c59b21fffc6b6e1e05022bb6b84fb74Keisuke Kuroyanagi insertedPointIndex + 1, CharUtils::toBaseLowerCase(dicNode->getNodeCodePoint())); 140a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const float weightedDistance = dist * ScoringParams::DISTANCE_WEIGHT_LENGTH; 14109858cbde49c086dd1d4d3050b57f0ea1774158bKeisuke Kuroynagi const bool singleChar = dicNode->getNodeCodePointCount() == 1; 14224706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi float cost = (singleChar ? ScoringParams::INSERTION_COST_FIRST_CHAR : 0.0f); 14324706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi if (sameCodePoint) { 14424706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi cost += ScoringParams::INSERTION_COST_SAME_CHAR; 14524706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi } else if (existsAdjacentProximityChars) { 14624706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi cost += ScoringParams::INSERTION_COST_PROXIMITY_CHAR; 14724706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi } else { 14824706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi cost += ScoringParams::INSERTION_COST; 14924706f8f5c61785006af50cc19fdd96559faa9faKeisuke Kuroynagi } 150a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return cost + weightedDistance; 151a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 152a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 1538a809f3433c3b96a3a9002a5bdc166f8c689eeb0Keisuke Kuroyanagi float getSpaceOmissionCost(const DicTraverseSession *const traverseSession, 1546bfeeb86947eb2131408ae8bd55a7f90486feb1dKeisuke Kuroynagi const DicNode *const dicNode, DicNode_InputStateG *inputStateG) const { 1558a809f3433c3b96a3a9002a5bdc166f8c689eeb0Keisuke Kuroyanagi const float cost = ScoringParams::SPACE_OMISSION_COST; 1568a809f3433c3b96a3a9002a5bdc166f8c689eeb0Keisuke Kuroyanagi return cost * traverseSession->getMultiWordCostMultiplier(); 157a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 158a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 1596bfeeb86947eb2131408ae8bd55a7f90486feb1dKeisuke Kuroynagi float getNewWordBigramLanguageCost(const DicTraverseSession *const traverseSession, 160866a6ced571a24f0f1b927aeccad7a1969da23b7Ken Wakasa const DicNode *const dicNode, 1619559dd2e30de288a9ff7069bfc59f8500b949a88Tom Ouyang MultiBigramMap *const multiBigramMap) const { 162d81654cd61bd10f7cb56bfa4c89b34e9cfb18598Keisuke Kuroyanagi return DicNodeUtils::getBigramNodeImprobability( 163d81654cd61bd10f7cb56bfa4c89b34e9cfb18598Keisuke Kuroyanagi traverseSession->getDictionaryStructurePolicy(), 1649559dd2e30de288a9ff7069bfc59f8500b949a88Tom Ouyang dicNode, multiBigramMap) * ScoringParams::DISTANCE_WEIGHT_LANGUAGE; 165a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 166a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 167a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka float getCompletionCost(const DicTraverseSession *const traverseSession, 168a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const DicNode *const dicNode) const { 169a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka // The auto completion starts when the input index is same as the input size 170a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const bool firstCompletion = dicNode->getInputIndex(0) 171a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka == traverseSession->getInputSize(); 172a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka // TODO: Change the cost for the first completion for the gesture? 17377de3a4b65d9baa9cc9469c2600bcce8de32ba82Keisuke Kuroyanagi const float cost = firstCompletion ? ScoringParams::COST_FIRST_COMPLETION 17477de3a4b65d9baa9cc9469c2600bcce8de32ba82Keisuke Kuroyanagi : ScoringParams::COST_COMPLETION; 175a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return cost; 176a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 177a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 178a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka float getTerminalLanguageCost(const DicTraverseSession *const traverseSession, 179a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const DicNode *const dicNode, const float dicNodeLanguageImprobability) const { 18034047d8905fbd2cbe4c99618aab105556ebee9edKeisuke Kuroynagi return dicNodeLanguageImprobability * ScoringParams::DISTANCE_WEIGHT_LANGUAGE; 181a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 182a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 18375322cecb9fe02a0914b65c859cfbc2f4e1f70d9Satoshi Kataoka float getTerminalInsertionCost(const DicTraverseSession *const traverseSession, 18475322cecb9fe02a0914b65c859cfbc2f4e1f70d9Satoshi Kataoka const DicNode *const dicNode) const { 18575322cecb9fe02a0914b65c859cfbc2f4e1f70d9Satoshi Kataoka const int inputIndex = dicNode->getInputIndex(0); 18675322cecb9fe02a0914b65c859cfbc2f4e1f70d9Satoshi Kataoka const int inputSize = traverseSession->getInputSize(); 18775322cecb9fe02a0914b65c859cfbc2f4e1f70d9Satoshi Kataoka ASSERT(inputIndex < inputSize); 18875322cecb9fe02a0914b65c859cfbc2f4e1f70d9Satoshi Kataoka // TODO: Implement more efficient logic 18975322cecb9fe02a0914b65c859cfbc2f4e1f70d9Satoshi Kataoka return ScoringParams::TERMINAL_INSERTION_COST * (inputSize - inputIndex); 19075322cecb9fe02a0914b65c859cfbc2f4e1f70d9Satoshi Kataoka } 19175322cecb9fe02a0914b65c859cfbc2f4e1f70d9Satoshi Kataoka 192a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE bool needsToNormalizeCompoundDistance() const { 193a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return false; 194a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 195a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 196a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE float getAdditionalProximityCost() const { 197a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return ScoringParams::ADDITIONAL_PROXIMITY_COST; 198a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 199a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 200a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE float getSubstitutionCost() const { 201a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return ScoringParams::SUBSTITUTION_COST; 202a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 203a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 204866a6ced571a24f0f1b927aeccad7a1969da23b7Ken Wakasa AK_FORCE_INLINE float getSpaceSubstitutionCost(const DicTraverseSession *const traverseSession, 205252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka const DicNode *const dicNode) const { 2068a809f3433c3b96a3a9002a5bdc166f8c689eeb0Keisuke Kuroyanagi const int inputIndex = dicNode->getInputIndex(0); 2078a809f3433c3b96a3a9002a5bdc166f8c689eeb0Keisuke Kuroyanagi const float distanceToSpaceKey = traverseSession->getProximityInfoState(0) 2088a809f3433c3b96a3a9002a5bdc166f8c689eeb0Keisuke Kuroyanagi ->getPointToKeyLength(inputIndex, KEYCODE_SPACE); 2098a809f3433c3b96a3a9002a5bdc166f8c689eeb0Keisuke Kuroyanagi const float cost = ScoringParams::SPACE_SUBSTITUTION_COST * distanceToSpaceKey; 210252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka return cost * traverseSession->getMultiWordCostMultiplier(); 211a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 212a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 2132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa ErrorTypeUtils::ErrorType getErrorType(const CorrectionType correctionType, 21460a169f0c34bf0da89c420d99bfff5c2556f3fbfKeisuke Kuroynagi const DicTraverseSession *const traverseSession, 21560a169f0c34bf0da89c420d99bfff5c2556f3fbfKeisuke Kuroynagi const DicNode *const parentDicNode, const DicNode *const dicNode) const; 21660a169f0c34bf0da89c420d99bfff5c2556f3fbfKeisuke Kuroynagi 217a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka private: 218a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka DISALLOW_COPY_AND_ASSIGN(TypingWeighting); 219a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka static const TypingWeighting sInstance; 220a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 221a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka TypingWeighting() {} 222a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka ~TypingWeighting() {} 223a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka}; 224a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka} // namespace latinime 225a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka#endif // LATINIME_TYPING_WEIGHTING_H 226