1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.ximtec.igesture.algorithm.rubinebd;
28
29 import java.math.BigDecimal;
30 import java.util.ArrayList;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.concurrent.CountDownLatch;
35 import java.util.logging.Level;
36 import java.util.logging.Logger;
37
38 import org.apache.commons.math.linear.BigMatrix;
39 import org.apache.commons.math.linear.BigMatrixImpl;
40 import org.sigtec.ink.Note;
41 import org.ximtec.igesture.algorithm.feature.FeatureException;
42 import org.ximtec.igesture.core.Gesture;
43 import org.ximtec.igesture.core.GestureClass;
44 import org.ximtec.igesture.core.SampleDescriptor;
45 import org.ximtec.igesture.util.BDVectorTools;
46 import org.ximtec.igesture.util.BigDecimalVector;
47 import org.ximtec.igesture.util.DoubleVector;
48
49
50
51
52
53
54
55
56 public class GestureClassHelper implements Runnable{
57
58 private static final Logger LOGGER = Logger.getLogger(GestureClassHelper.class.getName());
59
60 private GestureClass gestureClass;
61 private RubineConfiguration configuration;
62
63 private List<Gesture<Note>> samples;
64 private BigDecimalVector meanFeatureVector;
65
66
67
68 private Map<Gesture<Note>, GestureSampleHelper> sampleFeatureVector;
69
70 private BigMatrixImpl realMatrix;
71
72 private BigDecimal initialWeight;
73
74 private BigDecimalVector weightsVector;
75
76 private CountDownLatch latch;
77
78 public GestureClassHelper(GestureClass gestureClass, RubineConfiguration configuration, CountDownLatch latch){
79 this.gestureClass = gestureClass;
80 this.samples = getSamples();
81 this.configuration = configuration;
82 this.sampleFeatureVector = new HashMap<Gesture<Note>, GestureSampleHelper>();
83 this.latch = latch;
84
85 LOGGER.setLevel(Level.SEVERE);
86 }
87
88
89
90
91
92
93
94
95
96 private void computeFeatureVectors(GestureClass gestureClass) throws FeatureException {
97
98
99 List<BigDecimalVector> vectors = new ArrayList<BigDecimalVector>();
100
101 for (Gesture<Note> sample : samples) {
102 try{
103
104
105
106
107
108
109
110
111
112
113 GestureSampleHelper helper = new GestureSampleHelper(sample.getGesture(), configuration);
114 sampleFeatureVector.put(sample, helper);
115
116 if(BDVectorTools.hasValidValues(helper.getFeatureVector())){
117 vectors.add(helper.getFeatureVector());
118 }
119 }catch(FeatureException exception){
120 LOGGER.warning("Could not compute the Feature Vector.");
121 }
122 }
123
124
125
126
127
128
129
130 if(vectors.size() > 0){
131 meanFeatureVector = BDVectorTools.mean(vectors);
132 }else{
133 throw new FeatureException("There are not enough samples for Gesture Class"+gestureClass.getName());
134 }
135 }
136
137
138
139
140
141 private List<Gesture<Note>> getSamples(){
142 SampleDescriptor descriptor = gestureClass.getDescriptor(SampleDescriptor.class);
143 return descriptor.getSamples();
144 }
145
146 @Override
147 public void run(){
148 try {
149 computeFeatureVectors(gestureClass);
150 }
151 catch (FeatureException exception) {
152 exception.printStackTrace();
153
154 }
155
156 getCovarianceMatrix();
157
158 latch.countDown();
159 }
160
161
162
163
164
165
166
167
168 public BigMatrixImpl getCovarianceMatrix() {
169
170 if (realMatrix == null) {
171 int numOfFeatures = configuration.getNumberOfFeatures();
172 BigDecimal[][] matrix = new BigDecimal[numOfFeatures][numOfFeatures];
173
174 for (int i = 0; i < numOfFeatures; i++) {
175
176 for (int j = 0; j < numOfFeatures; j++) {
177 BigDecimal sum = new BigDecimal(0);
178
179 for (Gesture<?> sample : samples) {
180 try{
181 BigDecimal a1 = sampleFeatureVector.get(sample).getFeatureVector().get(i).subtract(meanFeatureVector.get(i));
182 BigDecimal a2 = sampleFeatureVector.get(sample).getFeatureVector().get(j).subtract(meanFeatureVector.get(j));
183 sum = sum.add(a1.multiply(a2));
184 }catch(Exception e){
185 e.printStackTrace();
186 }
187 }
188 matrix[i][j] = sum;
189 }
190 }
191
192 realMatrix = new BigMatrixImpl(matrix);
193 }
194
195 return realMatrix;
196 }
197
198 public BigDecimalVector getMeanFeatureVector(){
199 return meanFeatureVector;
200 }
201
202 public int getNumberOfSamples(){
203 return samples.size();
204 }
205
206 public void computeWeights(BigMatrix inverse){
207 weightsVector = new BigDecimalVector(meanFeatureVector.size());
208
209 for (int j = 0; j < meanFeatureVector.size(); j++) {
210 BigDecimal wci = new BigDecimal(0);
211
212 for (int i = 0; i < meanFeatureVector.size(); i++) {
213 wci = wci.add(inverse.getEntry(i, j).multiply(meanFeatureVector.get(i)));
214 }
215
216 weightsVector.set(j, wci);
217 }
218
219
220 BigDecimal wc0 = new BigDecimal(0);
221
222
223 for (int f = 0; f < meanFeatureVector.size(); f++) {
224 wc0 = wc0.add(weightsVector.get(f).multiply( meanFeatureVector.get(f)));
225 }
226
227 this.initialWeight = wc0.multiply(new BigDecimal(-0.5));
228 }
229
230 public BigDecimal getInitialWeight(){
231 return initialWeight;
232 }
233
234 public BigDecimalVector getWeights(){
235 return weightsVector;
236 }
237
238 public GestureClass getGestureClass(){
239 return gestureClass;
240 }
241
242
243 }