proximity_info_state.h revision ee62b78c9675bddaf2437e0cf521f6115e1d9feb
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef LATINIME_PROXIMITY_INFO_STATE_H
18#define LATINIME_PROXIMITY_INFO_STATE_H
19
20#include <bitset>
21#include <cstring> // for memset()
22#include <vector>
23
24#include "char_utils.h"
25#include "defines.h"
26#include "hash_map_compat.h"
27#include "proximity_info_params.h"
28#include "proximity_info_state_utils.h"
29
30namespace latinime {
31
32class ProximityInfo;
33
34class ProximityInfoState {
35 public:
36    typedef std::bitset<MAX_KEY_COUNT_IN_A_KEYBOARD> NearKeycodesSet;
37    static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
38    static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR;
39    static const float NOT_A_DISTANCE_FLOAT;
40    static const int NOT_A_CODE;
41
42    /////////////////////////////////////////
43    // Defined in proximity_info_state.cpp //
44    /////////////////////////////////////////
45    void initInputParams(const int pointerId, const float maxPointToKeyLength,
46            const ProximityInfo *proximityInfo, const int *const inputCodes,
47            const int inputSize, const int *xCoordinates, const int *yCoordinates,
48            const int *const times, const int *const pointerIds, const bool isGeometric);
49
50    /////////////////////////////////////////
51    // Defined here                        //
52    /////////////////////////////////////////
53    AK_FORCE_INLINE ProximityInfoState()
54            : mProximityInfo(0), mMaxPointToKeyLength(0.0f), mAverageSpeed(0.0f),
55              mHasTouchPositionCorrectionData(false), mMostCommonKeyWidthSquare(0),
56              mKeyCount(0), mCellHeight(0), mCellWidth(0), mGridHeight(0), mGridWidth(0),
57              mIsContinuationPossible(false), mSampledInputXs(), mSampledInputYs(), mTimes(),
58              mInputIndice(), mLengthCache(), mBeelineSpeedPercentiles(), mDistanceCache_G(),
59              mSpeedRates(), mDirections(), mCharProbabilities(), mNearKeysVector(),
60              mSearchKeysVector(), mTouchPositionCorrectionEnabled(false), mSampledInputSize(0) {
61        memset(mInputProximities, 0, sizeof(mInputProximities));
62        memset(mNormalizedSquaredDistances, 0, sizeof(mNormalizedSquaredDistances));
63        memset(mPrimaryInputWord, 0, sizeof(mPrimaryInputWord));
64    }
65
66    // Non virtual inline destructor -- never inherit this class
67    AK_FORCE_INLINE ~ProximityInfoState() {}
68
69    inline int getPrimaryCodePointAt(const int index) const {
70        return getProximityCodePointsAt(index)[0];
71    }
72
73    AK_FORCE_INLINE bool existsCodePointInProximityAt(const int index, const int c) const {
74        const int *codePoints = getProximityCodePointsAt(index);
75        int i = 0;
76        while (codePoints[i] > 0 && i < MAX_PROXIMITY_CHARS_SIZE_INTERNAL) {
77            if (codePoints[i++] == c) {
78                return true;
79            }
80        }
81        return false;
82    }
83
84    inline bool existsAdjacentProximityChars(const int index) const {
85        if (index < 0 || index >= mSampledInputSize) return false;
86        const int currentCodePoint = getPrimaryCodePointAt(index);
87        const int leftIndex = index - 1;
88        if (leftIndex >= 0 && existsCodePointInProximityAt(leftIndex, currentCodePoint)) {
89            return true;
90        }
91        const int rightIndex = index + 1;
92        if (rightIndex < mSampledInputSize
93                && existsCodePointInProximityAt(rightIndex, currentCodePoint)) {
94            return true;
95        }
96        return false;
97    }
98
99    inline int getNormalizedSquaredDistance(
100            const int inputIndex, const int proximityIndex) const {
101        return mNormalizedSquaredDistances[
102                inputIndex * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + proximityIndex];
103    }
104
105    inline const int *getPrimaryInputWord() const {
106        return mPrimaryInputWord;
107    }
108
109    inline bool touchPositionCorrectionEnabled() const {
110        return mTouchPositionCorrectionEnabled;
111    }
112
113    inline bool sameAsTyped(const int *word, int length) const {
114        if (length != mSampledInputSize) {
115            return false;
116        }
117        const int *inputProximities = mInputProximities;
118        while (length--) {
119            if (*inputProximities != *word) {
120                return false;
121            }
122            inputProximities += MAX_PROXIMITY_CHARS_SIZE_INTERNAL;
123            word++;
124        }
125        return true;
126    }
127
128    int getDuration(const int index) const;
129
130    bool isUsed() const {
131        return mSampledInputSize > 0;
132    }
133
134    int size() const {
135        return mSampledInputSize;
136    }
137
138    int getInputX(const int index) const {
139        return mSampledInputXs[index];
140    }
141
142    int getInputY(const int index) const {
143        return mSampledInputYs[index];
144    }
145
146    bool hasSpaceProximity(const int index) const;
147
148    int getLengthCache(const int index) const {
149        return mLengthCache[index];
150    }
151
152    bool isContinuationPossible() const {
153        return mIsContinuationPossible;
154    }
155
156    float getPointToKeyByIdLength(const int inputIndex, const int keyId, const float scale) const;
157    float getPointToKeyByIdLength(const int inputIndex, const int keyId) const;
158    float getPointToKeyLength(const int inputIndex, const int codePoint, const float scale) const;
159    float getPointToKeyLength_G(const int inputIndex, const int codePoint) const;
160
161    ProximityType getMatchedProximityId(const int index, const int c,
162            const bool checkProximityChars, int *proximityIndex = 0) const;
163
164    int getSpaceY() const;
165
166    int getAllPossibleChars(const size_t startIndex, int *const filter, const int filterSize) const;
167
168    float getSpeedRate(const int index) const {
169        return mSpeedRates[index];
170    }
171
172    AK_FORCE_INLINE int getBeelineSpeedPercentile(const int id) const {
173        return mBeelineSpeedPercentiles[id];
174    }
175
176    AK_FORCE_INLINE DoubleLetterLevel getDoubleLetterLevel(const int id) const {
177        const int beelineSpeedRate = getBeelineSpeedPercentile(id);
178        if (beelineSpeedRate == 0) {
179            return A_STRONG_DOUBLE_LETTER;
180        } else if (beelineSpeedRate
181                < ProximityInfoParams::MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE) {
182            return A_DOUBLE_LETTER;
183        } else {
184            return NOT_A_DOUBLE_LETTER;
185        }
186    }
187
188    float getDirection(const int index) const {
189        return mDirections[index];
190    }
191    // get xy direction
192    float getDirection(const int x, const int y) const;
193
194    float getPointAngle(const int index) const;
195    // Returns angle of three points. x, y, and z are indices.
196    float getPointsAngle(const int index0, const int index1, const int index2) const;
197
198    float getMostProbableString(int *const codePointBuf) const;
199
200    float getProbability(const int index, const int charCode) const;
201
202    float getLineToKeyDistance(
203            const int from, const int to, const int keyId, const bool extend) const;
204
205    bool isKeyInSerchKeysAfterIndex(const int index, const int keyId) const;
206 private:
207    DISALLOW_COPY_AND_ASSIGN(ProximityInfoState);
208    typedef hash_map_compat<int, float> NearKeysDistanceMap;
209    /////////////////////////////////////////
210    // Defined in proximity_info_state.cpp //
211    /////////////////////////////////////////
212    float calculateNormalizedSquaredDistance(const int keyIndex, const int inputIndex) const;
213
214    float calculateSquaredDistanceFromSweetSpotCenter(
215            const int keyIndex, const int inputIndex) const;
216
217    bool pushTouchPoint(const int inputIndex, const int nodeCodePoint, int x, int y, const int time,
218            const bool sample, const bool isLastPoint, const float sumAngle,
219            NearKeysDistanceMap *const currentNearKeysDistances,
220            const NearKeysDistanceMap *const prevNearKeysDistances,
221            const NearKeysDistanceMap *const prevPrevNearKeysDistances);
222    /////////////////////////////////////////
223    // Defined here                        //
224    /////////////////////////////////////////
225    inline float square(const float x) const { return x * x; }
226
227    bool hasInputCoordinates() const {
228        return mSampledInputXs.size() > 0 && mSampledInputYs.size() > 0;
229    }
230
231    inline const int *getProximityCodePointsAt(const int index) const {
232        return ProximityInfoStateUtils::getProximityCodePointsAt(mInputProximities, index);
233    }
234
235    float updateNearKeysDistances(const int x, const int y,
236            NearKeysDistanceMap *const currentNearKeysDistances);
237    bool isPrevLocalMin(const NearKeysDistanceMap *const currentNearKeysDistances,
238            const NearKeysDistanceMap *const prevNearKeysDistances,
239            const NearKeysDistanceMap *const prevPrevNearKeysDistances) const;
240    float getPointScore(
241            const int x, const int y, const int time, const bool last, const float nearest,
242            const float sumAngle, const NearKeysDistanceMap *const currentNearKeysDistances,
243            const NearKeysDistanceMap *const prevNearKeysDistances,
244            const NearKeysDistanceMap *const prevPrevNearKeysDistances) const;
245    bool checkAndReturnIsContinuationPossible(const int inputSize, const int *const xCoordinates,
246            const int *const yCoordinates, const int *const times, const bool isGeometric) const;
247    void popInputData();
248    void updateAlignPointProbabilities(const int start);
249    bool suppressCharProbabilities(const int index1, const int index2);
250    float calculateBeelineSpeedRate(const int id, const int inputSize,
251            const int *const xCoordinates, const int *const yCoordinates, const int * times) const;
252
253    // const
254    const ProximityInfo *mProximityInfo;
255    float mMaxPointToKeyLength;
256    float mAverageSpeed;
257    bool mHasTouchPositionCorrectionData;
258    int mMostCommonKeyWidthSquare;
259    int mKeyCount;
260    int mCellHeight;
261    int mCellWidth;
262    int mGridHeight;
263    int mGridWidth;
264    bool mIsContinuationPossible;
265
266    std::vector<int> mSampledInputXs;
267    std::vector<int> mSampledInputYs;
268    std::vector<int> mTimes;
269    std::vector<int> mInputIndice;
270    std::vector<int> mLengthCache;
271    std::vector<int> mBeelineSpeedPercentiles;
272    std::vector<float> mDistanceCache_G;
273    std::vector<float> mSpeedRates;
274    std::vector<float> mDirections;
275    // probabilities of skipping or mapping to a key for each point.
276    std::vector<hash_map_compat<int, float> > mCharProbabilities;
277    // The vector for the key code set which holds nearby keys for each sampled input point
278    // 1. Used to calculate the probability of the key
279    // 2. Used to calculate mSearchKeysVector
280    std::vector<NearKeycodesSet> mNearKeysVector;
281    // The vector for the key code set which holds nearby keys of some trailing sampled input points
282    // for each sampled input point. These nearby keys contain the next characters which can be in
283    // the dictionary. Specifically, currently we are looking for keys nearby trailing sampled
284    // inputs including the current input point.
285    std::vector<NearKeycodesSet> mSearchKeysVector;
286    bool mTouchPositionCorrectionEnabled;
287    int mInputProximities[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH];
288    int mNormalizedSquaredDistances[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH];
289    int mSampledInputSize;
290    int mPrimaryInputWord[MAX_WORD_LENGTH];
291};
292} // namespace latinime
293#endif // LATINIME_PROXIMITY_INFO_STATE_H
294