aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--native/jni/Android.mk7
-rw-r--r--native/jni/src/suggest/policyimpl/typing/scoring_params.cpp52
-rw-r--r--native/jni/src/suggest/policyimpl/typing/scoring_params.h66
-rw-r--r--native/jni/src/suggest/policyimpl/typing/typing_scoring.cpp21
-rw-r--r--native/jni/src/suggest/policyimpl/typing/typing_scoring.h82
-rw-r--r--native/jni/src/suggest/policyimpl/typing/typing_suggest_policy.h52
-rw-r--r--native/jni/src/suggest/policyimpl/typing/typing_traversal.cpp24
-rw-r--r--native/jni/src/suggest/policyimpl/typing/typing_traversal.h184
-rw-r--r--native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp23
-rw-r--r--native/jni/src/suggest/policyimpl/typing/typing_weighting.h194
10 files changed, 704 insertions, 1 deletions
diff --git a/native/jni/Android.mk b/native/jni/Android.mk
index 423c24e88..42275d45a 100644
--- a/native/jni/Android.mk
+++ b/native/jni/Android.mk
@@ -31,7 +31,8 @@ LOCAL_C_INCLUDES += \
$(LATIN_IME_SRC_FULLPATH_DIR)/suggest \
$(LATIN_IME_SRC_FULLPATH_DIR)/suggest/core/dicnode \
$(LATIN_IME_SRC_FULLPATH_DIR)/suggest/core/policy \
- $(LATIN_IME_SRC_FULLPATH_DIR)/suggest/core/session
+ $(LATIN_IME_SRC_FULLPATH_DIR)/suggest/core/session \
+ $(LATIN_IME_SRC_FULLPATH_DIR)/suggest/policyimpl/typing
LOCAL_CFLAGS += -Werror -Wall -Wextra -Weffc++ -Wformat=2 -Wcast-qual -Wcast-align \
-Wwrite-strings -Wfloat-equal -Wpointer-arith -Winit-self -Wredundant-decls -Wno-system-headers
@@ -69,6 +70,10 @@ LATIN_IME_CORE_SRC_FILES := \
suggest/core/dicnode/dic_node_utils.cpp \
suggest/core/policy/weighting.cpp \
suggest/core/session/dic_traverse_session.cpp \
+ suggest/policyimpl/typing/scoring_params.cpp \
+ suggest/policyimpl/typing/typing_scoring.cpp \
+ suggest/policyimpl/typing/typing_traversal.cpp \
+ suggest/policyimpl/typing/typing_weighting.cpp \
suggest/gesture_suggest.cpp \
suggest/typing_suggest.cpp
diff --git a/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp b/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp
new file mode 100644
index 000000000..90985d0fe
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "scoring_params.h"
+
+namespace latinime {
+// TODO: RENAME all
+const float ScoringParams::MAX_SPATIAL_DISTANCE = 1.0f;
+const int ScoringParams::THRESHOLD_NEXT_WORD_PROBABILITY = 40;
+const int ScoringParams::THRESHOLD_NEXT_WORD_PROBABILITY_FOR_CAPPED = 120;
+const float ScoringParams::AUTOCORRECT_OUTPUT_THRESHOLD = 1.0f;
+const int ScoringParams::MAX_CACHE_DIC_NODE_SIZE = 125;
+const int ScoringParams::THRESHOLD_SHORT_WORD_LENGTH = 4;
+
+const float ScoringParams::DISTANCE_WEIGHT_LENGTH = 0.132f;
+const float ScoringParams::PROXIMITY_COST = 0.086f;
+const float ScoringParams::FIRST_PROXIMITY_COST = 0.104f;
+const float ScoringParams::OMISSION_COST = 0.388f;
+const float ScoringParams::OMISSION_COST_SAME_CHAR = 0.431f;
+const float ScoringParams::OMISSION_COST_FIRST_CHAR = 0.532f;
+const float ScoringParams::INSERTION_COST = 0.670f;
+const float ScoringParams::INSERTION_COST_SAME_CHAR = 0.526f;
+const float ScoringParams::INSERTION_COST_FIRST_CHAR = 0.563f;
+const float ScoringParams::TRANSPOSITION_COST = 0.494f;
+const float ScoringParams::SPACE_SUBSTITUTION_COST = 0.239f;
+const float ScoringParams::ADDITIONAL_PROXIMITY_COST = 0.380f;
+const float ScoringParams::SUBSTITUTION_COST = 0.363f;
+const float ScoringParams::COST_NEW_WORD = 0.054f;
+const float ScoringParams::COST_NEW_WORD_CAPITALIZED = 0.174f;
+const float ScoringParams::DISTANCE_WEIGHT_LANGUAGE = 1.123f;
+const float ScoringParams::COST_FIRST_LOOKAHEAD = 0.462f;
+const float ScoringParams::COST_LOOKAHEAD = 0.092f;
+const float ScoringParams::HAS_PROXIMITY_TERMINAL_COST = 0.126f;
+const float ScoringParams::HAS_EDIT_CORRECTION_TERMINAL_COST = 0.056f;
+const float ScoringParams::HAS_MULTI_WORD_TERMINAL_COST = 0.136f;
+const float ScoringParams::TYPING_BASE_OUTPUT_SCORE = 1.0f;
+const float ScoringParams::TYPING_MAX_OUTPUT_SCORE_PER_INPUT = 0.1f;
+const float ScoringParams::MAX_NORM_DISTANCE_FOR_EDIT = 0.1f;
+} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/typing/scoring_params.h b/native/jni/src/suggest/policyimpl/typing/scoring_params.h
new file mode 100644
index 000000000..8f104b362
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/typing/scoring_params.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LATINIME_SCORING_PARAMS_H
+#define LATINIME_SCORING_PARAMS_H
+
+#include "defines.h"
+
+namespace latinime {
+
+class ScoringParams {
+ public:
+ // Fixed model parameters
+ static const float MAX_SPATIAL_DISTANCE;
+ static const int THRESHOLD_NEXT_WORD_PROBABILITY;
+ static const int THRESHOLD_NEXT_WORD_PROBABILITY_FOR_CAPPED;
+ static const float AUTOCORRECT_OUTPUT_THRESHOLD;
+ static const int MAX_CACHE_DIC_NODE_SIZE;
+ static const int THRESHOLD_SHORT_WORD_LENGTH;
+
+ // Numerically optimized parameters (currently for tap typing only).
+ // TODO: add ability to modify these constants programmatically.
+ // TODO: explore optimization of gesture parameters.
+ static const float DISTANCE_WEIGHT_LENGTH;
+ static const float PROXIMITY_COST;
+ static const float FIRST_PROXIMITY_COST;
+ static const float OMISSION_COST;
+ static const float OMISSION_COST_SAME_CHAR;
+ static const float OMISSION_COST_FIRST_CHAR;
+ static const float INSERTION_COST;
+ static const float INSERTION_COST_SAME_CHAR;
+ static const float INSERTION_COST_FIRST_CHAR;
+ static const float TRANSPOSITION_COST;
+ static const float SPACE_SUBSTITUTION_COST;
+ static const float ADDITIONAL_PROXIMITY_COST;
+ static const float SUBSTITUTION_COST;
+ static const float COST_NEW_WORD;
+ static const float COST_NEW_WORD_CAPITALIZED;
+ static const float DISTANCE_WEIGHT_LANGUAGE;
+ static const float COST_FIRST_LOOKAHEAD;
+ static const float COST_LOOKAHEAD;
+ static const float HAS_PROXIMITY_TERMINAL_COST;
+ static const float HAS_EDIT_CORRECTION_TERMINAL_COST;
+ static const float HAS_MULTI_WORD_TERMINAL_COST;
+ static const float TYPING_BASE_OUTPUT_SCORE;
+ static const float TYPING_MAX_OUTPUT_SCORE_PER_INPUT;
+ static const float MAX_NORM_DISTANCE_FOR_EDIT;
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ScoringParams);
+};
+} // namespace latinime
+#endif // LATINIME_SCORING_PARAMS_H
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_scoring.cpp b/native/jni/src/suggest/policyimpl/typing/typing_scoring.cpp
new file mode 100644
index 000000000..53f68f20f
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/typing/typing_scoring.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "typing_scoring.h"
+
+namespace latinime {
+const TypingScoring TypingScoring::sInstance;
+} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_scoring.h b/native/jni/src/suggest/policyimpl/typing/typing_scoring.h
new file mode 100644
index 000000000..ed941f0ae
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/typing/typing_scoring.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LATINIME_TYPING_SCORING_H
+#define LATINIME_TYPING_SCORING_H
+
+#include "defines.h"
+#include "scoring.h"
+#include "scoring_params.h"
+
+namespace latinime {
+
+class DicNode;
+class DicTraverseSession;
+
+class TypingScoring : public Scoring {
+ public:
+ static const TypingScoring *getInstance() { return &sInstance; }
+
+ AK_FORCE_INLINE bool getMostProbableString(
+ const DicTraverseSession *const traverseSession, const int terminalSize,
+ const float languageWeight, int *const outputCodePoints, int *const type,
+ int *const freq) const {
+ return false;
+ }
+
+ AK_FORCE_INLINE void safetyNetForMostProbableString(const int terminalSize,
+ const int maxScore, int *const outputCodePoints, int *const frequencies) const {
+ }
+
+ AK_FORCE_INLINE void searchWordWithDoubleLetter(DicNode *terminals,
+ const int terminalSize, int *doubleLetterTerminalIndex,
+ DoubleLetterLevel *doubleLetterLevel) const {
+ }
+
+ AK_FORCE_INLINE float getAdjustedLanguageWeight(DicTraverseSession *const traverseSession,
+ DicNode *const terminals, const int size) const {
+ return 1.0f;
+ }
+
+ AK_FORCE_INLINE int calculateFinalScore(const float compoundDistance,
+ const int inputSize, const bool forceCommit) const {
+ const float maxDistance = ScoringParams::DISTANCE_WEIGHT_LANGUAGE
+ + static_cast<float>(inputSize) * ScoringParams::TYPING_MAX_OUTPUT_SCORE_PER_INPUT;
+ return static_cast<int>((ScoringParams::TYPING_BASE_OUTPUT_SCORE
+ - (compoundDistance / maxDistance)
+ + (forceCommit ? ScoringParams::AUTOCORRECT_OUTPUT_THRESHOLD : 0.0f))
+ * SUGGEST_INTERFACE_OUTPUT_SCALE);
+ }
+
+ AK_FORCE_INLINE float getDoubleLetterDemotionDistanceCost(const int terminalIndex,
+ const int doubleLetterTerminalIndex,
+ const DoubleLetterLevel doubleLetterLevel) const {
+ return 0.0f;
+ }
+
+ AK_FORCE_INLINE bool doesAutoCorrectValidWord() const {
+ return false;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypingScoring);
+ static const TypingScoring sInstance;
+
+ TypingScoring() {}
+ ~TypingScoring() {}
+};
+} // namespace latinime
+#endif // LATINIME_TYPING_SCORING_H
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy.h b/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy.h
new file mode 100644
index 000000000..1f659c679
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LATINIME_TYPING_SUGGEST_POLICY_H
+#define LATINIME_TYPING_SUGGEST_POLICY_H
+
+#include "defines.h"
+#include "suggest_policy.h"
+#include "typing_scoring.h"
+#include "typing_traversal.h"
+#include "typing_weighting.h"
+
+namespace latinime {
+
+class Scoring;
+class Traversal;
+class Weighting;
+
+class TypingSuggestPolicy : public SuggestPolicy {
+ public:
+ TypingSuggestPolicy() {}
+ virtual ~TypingSuggestPolicy() {}
+ AK_FORCE_INLINE const Traversal *getTraversal() const {
+ return TypingTraversal::getInstance();
+ }
+
+ AK_FORCE_INLINE const Scoring *getScoring() const {
+ return TypingScoring::getInstance();
+ }
+
+ AK_FORCE_INLINE const Weighting *getWeighting() const {
+ return TypingWeighting::getInstance();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypingSuggestPolicy);
+};
+} // namespace latinime
+#endif // LATINIME_TYPING_SUGGEST_POLICY_H
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_traversal.cpp b/native/jni/src/suggest/policyimpl/typing/typing_traversal.cpp
new file mode 100644
index 000000000..68c614e77
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/typing/typing_traversal.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "typing_traversal.h"
+
+namespace latinime {
+const bool TypingTraversal::CORRECT_OMISSION = true;
+const bool TypingTraversal::CORRECT_SPACE_SUBSTITUTION = true;
+const bool TypingTraversal::CORRECT_SPACE_OMISSION = true;
+const TypingTraversal TypingTraversal::sInstance;
+} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_traversal.h b/native/jni/src/suggest/policyimpl/typing/typing_traversal.h
new file mode 100644
index 000000000..16153f8bb
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/typing/typing_traversal.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LATINIME_TYPING_TRAVERSAL_H
+#define LATINIME_TYPING_TRAVERSAL_H
+
+#include <stdint.h>
+
+#include "char_utils.h"
+#include "defines.h"
+#include "dic_node.h"
+#include "dic_node_vector.h"
+#include "dic_traverse_session.h"
+#include "proximity_info_state.h"
+#include "scoring_params.h"
+#include "traversal.h"
+
+namespace latinime {
+class TypingTraversal : public Traversal {
+ public:
+ static const TypingTraversal *getInstance() { return &sInstance; }
+
+ AK_FORCE_INLINE int getMaxPointerCount() const {
+ return MAX_POINTER_COUNT;
+ }
+
+ AK_FORCE_INLINE bool allowsErrorCorrections(const DicNode *const dicNode) const {
+ return dicNode->getNormalizedSpatialDistance()
+ < ScoringParams::MAX_NORM_DISTANCE_FOR_EDIT;
+ }
+
+ AK_FORCE_INLINE bool isOmission(const DicTraverseSession *const traverseSession,
+ const DicNode *const dicNode, const DicNode *const childDicNode) const {
+ if (!CORRECT_OMISSION) {
+ return false;
+ }
+ const int inputSize = traverseSession->getInputSize();
+ // TODO: Don't refer to isCompletion?
+ if (dicNode->isCompletion(inputSize)) {
+ return false;
+ }
+ if (dicNode->canBeIntentionalOmission()) {
+ return true;
+ }
+ const int point0Index = dicNode->getInputIndex(0);
+ const int currentBaseLowerCodePoint =
+ toBaseLowerCase(childDicNode->getNodeCodePoint());
+ const int typedBaseLowerCodePoint =
+ toBaseLowerCase(traverseSession->getProximityInfoState(0)
+ ->getPrimaryCodePointAt(point0Index));
+ return (currentBaseLowerCodePoint != typedBaseLowerCodePoint);
+ }
+
+ AK_FORCE_INLINE bool isSpaceSubstitutionTerminal(
+ const DicTraverseSession *const traverseSession, const DicNode *const dicNode) const {
+ if (!CORRECT_SPACE_SUBSTITUTION) {
+ return false;
+ }
+ if (!canDoLookAheadCorrection(traverseSession, dicNode)) {
+ return false;
+ }
+ const int point0Index = dicNode->getInputIndex(0);
+ return dicNode->isTerminalWordNode()
+ && traverseSession->getProximityInfoState(0)->
+ hasSpaceProximity(point0Index);
+ }
+
+ AK_FORCE_INLINE bool isSpaceOmissionTerminal(
+ const DicTraverseSession *const traverseSession, const DicNode *const dicNode) const {
+ if (!CORRECT_SPACE_OMISSION) {
+ return false;
+ }
+ const int inputSize = traverseSession->getInputSize();
+ // TODO: Don't refer to isCompletion?
+ if (dicNode->isCompletion(inputSize)) {
+ return false;
+ }
+ if (!dicNode->isTerminalWordNode()) {
+ return false;
+ }
+ const int16_t pointIndex = dicNode->getInputIndex(0);
+ return pointIndex <= inputSize && !dicNode->isTotalInputSizeExceedingLimit()
+ && !dicNode->shouldBeFilterdBySafetyNetForBigram();
+ }
+
+ AK_FORCE_INLINE bool shouldDepthLevelCache(
+ const DicTraverseSession *const traverseSession) const {
+ const int inputSize = traverseSession->getInputSize();
+ return traverseSession->isCacheBorderForTyping(inputSize);
+ }
+
+ AK_FORCE_INLINE bool shouldNodeLevelCache(
+ const DicTraverseSession *const traverseSession, const DicNode *const dicNode) const {
+ return false;
+ }
+
+ AK_FORCE_INLINE bool canDoLookAheadCorrection(
+ const DicTraverseSession *const traverseSession, const DicNode *const dicNode) const {
+ const int inputSize = traverseSession->getInputSize();
+ return dicNode->canDoLookAheadCorrection(inputSize);
+ }
+
+ AK_FORCE_INLINE ProximityType getProximityType(
+ const DicTraverseSession *const traverseSession, const DicNode *const dicNode,
+ const DicNode *const childDicNode) const {
+ return traverseSession->getProximityInfoState(0)->getProximityType(
+ dicNode->getInputIndex(0), childDicNode->getNodeCodePoint(),
+ true /* checkProximityChars */);
+ }
+
+ AK_FORCE_INLINE bool needsToTraverseAllUserInput() const {
+ return true;
+ }
+
+ AK_FORCE_INLINE float getMaxSpatialDistance() const {
+ return ScoringParams::MAX_SPATIAL_DISTANCE;
+ }
+
+ AK_FORCE_INLINE bool allowPartialCommit() const {
+ return true;
+ }
+
+ AK_FORCE_INLINE int getDefaultExpandDicNodeSize() const {
+ return DicNodeVector::DEFAULT_NODES_SIZE_FOR_OPTIMIZATION;
+ }
+
+ AK_FORCE_INLINE bool sameAsTyped(
+ const DicTraverseSession *const traverseSession, const DicNode *const dicNode) const {
+ return traverseSession->getProximityInfoState(0)->sameAsTyped(
+ dicNode->getOutputWordBuf(), dicNode->getDepth());
+ }
+
+ AK_FORCE_INLINE int getMaxCacheSize() const {
+ return ScoringParams::MAX_CACHE_DIC_NODE_SIZE;
+ }
+
+ AK_FORCE_INLINE bool isPossibleOmissionChildNode(
+ const DicTraverseSession *const traverseSession, const DicNode *const parentDicNode,
+ const DicNode *const dicNode) const {
+ const ProximityType proximityType =
+ getProximityType(traverseSession, parentDicNode, dicNode);
+ if (!DicNodeUtils::isProximityChar(proximityType)) {
+ return false;
+ }
+ return true;
+ }
+
+ AK_FORCE_INLINE bool isGoodToTraverseNextWord(const DicNode *const dicNode) const {
+ const int probability = dicNode->getProbability();
+ if (probability < ScoringParams::THRESHOLD_NEXT_WORD_PROBABILITY) {
+ return false;
+ }
+ const int c = dicNode->getOutputWordBuf()[0];
+ const bool shortCappedWord = dicNode->getDepth()
+ < ScoringParams::THRESHOLD_SHORT_WORD_LENGTH && isAsciiUpper(c);
+ return !shortCappedWord
+ || probability >= ScoringParams::THRESHOLD_NEXT_WORD_PROBABILITY_FOR_CAPPED;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypingTraversal);
+ static const bool CORRECT_OMISSION;
+ static const bool CORRECT_SPACE_SUBSTITUTION;
+ static const bool CORRECT_SPACE_OMISSION;
+ static const TypingTraversal sInstance;
+
+ TypingTraversal() {}
+ ~TypingTraversal() {}
+};
+} // namespace latinime
+#endif // LATINIME_TYPING_TRAVERSAL_H
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp b/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp
new file mode 100644
index 000000000..6e4b2fb6a
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "dic_node.h"
+#include "scoring_params.h"
+#include "typing_weighting.h"
+
+namespace latinime {
+const TypingWeighting TypingWeighting::sInstance;
+} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_weighting.h b/native/jni/src/suggest/policyimpl/typing/typing_weighting.h
new file mode 100644
index 000000000..e8075f41a
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/typing/typing_weighting.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LATINIME_TYPING_WEIGHTING_H
+#define LATINIME_TYPING_WEIGHTING_H
+
+#include "defines.h"
+#include "dic_node_utils.h"
+#include "dic_traverse_session.h"
+#include "weighting.h"
+
+namespace latinime {
+
+class DicNode;
+struct DicNode_InputStateG;
+
+class TypingWeighting : public Weighting {
+ public:
+ static const TypingWeighting *getInstance() { return &sInstance; }
+
+ protected:
+ float getTerminalSpatialCost(
+ const DicTraverseSession *const traverseSession, const DicNode *const dicNode) const {
+ float cost = 0.0f;
+ if (dicNode->hasMultipleWords()) {
+ cost += ScoringParams::HAS_MULTI_WORD_TERMINAL_COST;
+ }
+ if (dicNode->getProximityCorrectionCount() > 0) {
+ cost += ScoringParams::HAS_PROXIMITY_TERMINAL_COST;
+ }
+ if (dicNode->getEditCorrectionCount() > 0) {
+ cost += ScoringParams::HAS_EDIT_CORRECTION_TERMINAL_COST;
+ }
+ return cost;
+ }
+
+ float getOmissionCost(const DicNode *const parentDicNode, const DicNode *const dicNode) const {
+ bool sameCodePoint = false;
+ bool isFirstLetterOmission = false;
+ float cost = 0.0f;
+ sameCodePoint = dicNode->isSameNodeCodePoint(parentDicNode);
+ // If the traversal omitted the first letter then the dicNode should now be on the second.
+ isFirstLetterOmission = dicNode->getDepth() == 2;
+ if (isFirstLetterOmission) {
+ cost = ScoringParams::OMISSION_COST_FIRST_CHAR;
+ } else {
+ cost = sameCodePoint ? ScoringParams::OMISSION_COST_SAME_CHAR
+ : ScoringParams::OMISSION_COST;
+ }
+ return cost;
+ }
+
+ float getMatchedCost(
+ const DicTraverseSession *const traverseSession, const DicNode *const dicNode,
+ DicNode_InputStateG *inputStateG) const {
+ const int pointIndex = dicNode->getInputIndex(0);
+ // Note: min() required since length can be MAX_POINT_TO_KEY_LENGTH for characters not on
+ // the keyboard (like accented letters)
+ const float length = min(ScoringParams::MAX_SPATIAL_DISTANCE,
+ traverseSession->getProximityInfoState(0)->getPointToKeyLength(
+ pointIndex, dicNode->getNodeCodePoint()));
+ const float weightedDistance = length * ScoringParams::DISTANCE_WEIGHT_LENGTH;
+ const bool isFirstChar = pointIndex == 0;
+ const bool isProximity = isProximityDicNode(traverseSession, dicNode);
+ const float cost = isProximity ? (isFirstChar ? ScoringParams::FIRST_PROXIMITY_COST
+ : ScoringParams::PROXIMITY_COST) : 0.0f;
+ return weightedDistance + cost;
+ }
+
+ bool isProximityDicNode(
+ const DicTraverseSession *const traverseSession, const DicNode *const dicNode) const {
+ const int pointIndex = dicNode->getInputIndex(0);
+ const int primaryCodePoint = toBaseLowerCase(
+ traverseSession->getProximityInfoState(0)->getPrimaryCodePointAt(pointIndex));
+ const int dicNodeChar = toBaseLowerCase(dicNode->getNodeCodePoint());
+ return primaryCodePoint != dicNodeChar;
+ }
+
+ float getTranspositionCost(
+ const DicTraverseSession *const traverseSession, const DicNode *const parentDicNode,
+ const DicNode *const dicNode) const {
+ const int16_t parentPointIndex = parentDicNode->getInputIndex(0);
+ const int prevCodePoint = parentDicNode->getNodeCodePoint();
+ const float distance1 = traverseSession->getProximityInfoState(0)->getPointToKeyLength(
+ parentPointIndex + 1, prevCodePoint);
+ const int codePoint = dicNode->getNodeCodePoint();
+ const float distance2 = traverseSession->getProximityInfoState(0)->getPointToKeyLength(
+ parentPointIndex, codePoint);
+ const float distance = distance1 + distance2;
+ const float weightedLengthDistance =
+ distance * ScoringParams::DISTANCE_WEIGHT_LENGTH;
+ return ScoringParams::TRANSPOSITION_COST + weightedLengthDistance;
+ }
+
+ float getInsertionCost(
+ const DicTraverseSession *const traverseSession,
+ const DicNode *const parentDicNode, const DicNode *const dicNode) const {
+ const int16_t parentPointIndex = parentDicNode->getInputIndex(0);
+ const int prevCodePoint =
+ traverseSession->getProximityInfoState(0)->getPrimaryCodePointAt(parentPointIndex);
+
+ const int currentCodePoint = dicNode->getNodeCodePoint();
+ const bool sameCodePoint = prevCodePoint == currentCodePoint;
+ const float dist = traverseSession->getProximityInfoState(0)->getPointToKeyLength(
+ parentPointIndex + 1, currentCodePoint);
+ const float weightedDistance = dist * ScoringParams::DISTANCE_WEIGHT_LENGTH;
+ const bool singleChar = dicNode->getDepth() == 1;
+ const float cost = (singleChar ? ScoringParams::INSERTION_COST_FIRST_CHAR : 0.0f)
+ + (sameCodePoint ? ScoringParams::INSERTION_COST_SAME_CHAR
+ : ScoringParams::INSERTION_COST);
+ return cost + weightedDistance;
+ }
+
+ float getNewWordCost(const DicNode *const dicNode) const {
+ const bool isCapitalized = dicNode->isCapitalized();
+ return isCapitalized ?
+ ScoringParams::COST_NEW_WORD_CAPITALIZED : ScoringParams::COST_NEW_WORD;
+ }
+
+ float getNewWordBigramCost(
+ const DicTraverseSession *const traverseSession, const DicNode *const dicNode,
+ hash_map_compat<int, int16_t> *const bigramCacheMap) const {
+ return DicNodeUtils::getBigramNodeImprobability(traverseSession->getOffsetDict(),
+ dicNode, bigramCacheMap);
+ }
+
+ float getCompletionCost(const DicTraverseSession *const traverseSession,
+ const DicNode *const dicNode) const {
+ // The auto completion starts when the input index is same as the input size
+ const bool firstCompletion = dicNode->getInputIndex(0)
+ == traverseSession->getInputSize();
+ // TODO: Change the cost for the first completion for the gesture?
+ const float cost = firstCompletion ? ScoringParams::COST_FIRST_LOOKAHEAD
+ : ScoringParams::COST_LOOKAHEAD;
+ return cost;
+ }
+
+ float getTerminalLanguageCost(const DicTraverseSession *const traverseSession,
+ const DicNode *const dicNode, const float dicNodeLanguageImprobability) const {
+ const bool hasEditCount = dicNode->getEditCorrectionCount() > 0;
+ const bool isSameLength = dicNode->getDepth() == traverseSession->getInputSize();
+ const bool hasMultipleWords = dicNode->hasMultipleWords();
+ const bool hasProximityErrors = dicNode->getProximityCorrectionCount() > 0;
+ // Gesture input is always assumed to have proximity errors
+ // because the input word shouldn't be treated as perfect
+ const bool isExactMatch = !hasEditCount && !hasMultipleWords
+ && !hasProximityErrors && isSameLength;
+
+ const float totalPrevWordsLanguageCost = dicNode->getTotalPrevWordsLanguageCost();
+ const float languageImprobability = isExactMatch ? 0.0f : dicNodeLanguageImprobability;
+ const float languageWeight = ScoringParams::DISTANCE_WEIGHT_LANGUAGE;
+ // TODO: Caveat: The following equation should be:
+ // totalPrevWordsLanguageCost + (languageImprobability * languageWeight);
+ return (totalPrevWordsLanguageCost + languageImprobability) * languageWeight;
+ }
+
+ AK_FORCE_INLINE bool needsToNormalizeCompoundDistance() const {
+ return false;
+ }
+
+ AK_FORCE_INLINE float getAdditionalProximityCost() const {
+ return ScoringParams::ADDITIONAL_PROXIMITY_COST;
+ }
+
+ AK_FORCE_INLINE float getSubstitutionCost() const {
+ return ScoringParams::SUBSTITUTION_COST;
+ }
+
+ AK_FORCE_INLINE float getSpaceSubstitutionCost() const {
+ return ScoringParams::SPACE_SUBSTITUTION_COST;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypingWeighting);
+ static const TypingWeighting sInstance;
+
+ TypingWeighting() {}
+ ~TypingWeighting() {}
+};
+} // namespace latinime
+#endif // LATINIME_TYPING_WEIGHTING_H