• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 package com.android.systemui.classifier;
18 
19 import android.os.SystemClock;
20 
21 import java.util.ArrayList;
22 
23 /**
24  * Holds the evaluations for ended strokes and gestures. These values are decreased through time.
25  */
26 public class HistoryEvaluator {
27     private static final float INTERVAL = 50.0f;
28     private static final float HISTORY_FACTOR = 0.9f;
29     private static final float EPSILON = 1e-5f;
30 
31     private final ArrayList<Data> mStrokes = new ArrayList<>();
32     private final ArrayList<Data> mGestureWeights = new ArrayList<>();
33     private long mLastUpdate;
34 
HistoryEvaluator()35     public HistoryEvaluator() {
36         mLastUpdate = SystemClock.elapsedRealtime();
37     }
38 
addStroke(float evaluation)39     public void addStroke(float evaluation) {
40         decayValue();
41         mStrokes.add(new Data(evaluation));
42     }
43 
addGesture(float evaluation)44     public void addGesture(float evaluation) {
45         decayValue();
46         mGestureWeights.add(new Data(evaluation));
47     }
48 
49     /**
50      * Calculates the weighted average of strokes and adds to it the weighted average of gestures
51      */
getEvaluation()52     public float getEvaluation() {
53         return weightedAverage(mStrokes) + weightedAverage(mGestureWeights);
54     }
55 
weightedAverage(ArrayList<Data> list)56     private float weightedAverage(ArrayList<Data> list) {
57         float sumValue = 0.0f;
58         float sumWeight = 0.0f;
59         int size = list.size();
60         for (int i = 0; i < size; i++) {
61             Data data = list.get(i);
62             sumValue += data.evaluation * data.weight;
63             sumWeight += data.weight;
64         }
65 
66         if (sumWeight == 0.0f) {
67             return 0.0f;
68         }
69 
70         return sumValue / sumWeight;
71     }
72 
decayValue()73     private void decayValue() {
74         long time = SystemClock.elapsedRealtime();
75 
76         if (time <= mLastUpdate) {
77             return;
78         }
79 
80         // All weights are multiplied by HISTORY_FACTOR after each INTERVAL milliseconds.
81         float factor = (float) Math.pow(HISTORY_FACTOR, (time - mLastUpdate) / INTERVAL);
82 
83         decayValue(mStrokes, factor);
84         decayValue(mGestureWeights, factor);
85         mLastUpdate = time;
86     }
87 
decayValue(ArrayList<Data> list, float factor)88     private void decayValue(ArrayList<Data> list, float factor) {
89         int size = list.size();
90         for (int i = 0; i < size; i++) {
91             list.get(i).weight *= factor;
92         }
93 
94         // Removing evaluations with such small weights that they do not matter anymore
95         while (!list.isEmpty() && isZero(list.get(0).weight)) {
96             list.remove(0);
97         }
98     }
99 
isZero(float x)100     private boolean isZero(float x) {
101         return x <= EPSILON && x >= -EPSILON;
102     }
103 
104     /**
105      * For each stroke it holds its initial value and the current weight. Initially the
106      * weight is set to 1.0
107      */
108     private static class Data {
109         public float evaluation;
110         public float weight;
111 
Data(float evaluation)112         public Data(float evaluation) {
113             this.evaluation = evaluation;
114             weight = 1.0f;
115         }
116     }
117 }
118