andrew@28
|
1 /*
|
andrew@28
|
2 * BayesianArrayStructure.cpp
|
andrew@28
|
3 * midiCannamReader
|
andrew@28
|
4 *
|
andrew@28
|
5 * Created by Andrew on 17/07/2011.
|
andrew@28
|
6 * Copyright 2011 QMUL. All rights reserved.
|
andrew@28
|
7 *
|
andrew@28
|
8 */
|
andrew@28
|
9
|
andrew@28
|
10 //look at reset speed to one - what does this do? - get rid of?
|
andrew@28
|
11
|
andrew@28
|
12
|
andrew@28
|
13 #include "BayesianArrayStructure.h"
|
andrew@28
|
14
|
andrew@28
|
15 BayesianArrayStructure::BayesianArrayStructure(){
|
andrew@28
|
16 printf("Bayesian structure: DeFault constructor called");
|
andrew@30
|
17 usingIntegratedTempoEstimate = true;// use max index
|
andrew@28
|
18
|
andrew@28
|
19 relativeSpeedLikelihoodStdDev = 5.0;
|
andrew@28
|
20
|
andrew@28
|
21 prior.createVector(1);
|
andrew@28
|
22 likelihood.createVector(1);
|
andrew@28
|
23 posterior.createVector(1);
|
andrew@28
|
24
|
andrew@28
|
25
|
andrew@28
|
26 speedPriorValue = 1.0;
|
andrew@28
|
27 speedEstimate = speedPriorValue;
|
andrew@28
|
28
|
andrew@28
|
29 lastEventTime = 0;//ofGetElapsedTimeMillis();
|
andrew@28
|
30
|
andrew@28
|
31 tmpBestEstimate = 0;
|
andrew@28
|
32 crossUpdateTimeThreshold = 60;
|
andrew@28
|
33 priorWidth = 50;
|
andrew@28
|
34
|
andrew@28
|
35 }
|
andrew@28
|
36
|
andrew@28
|
37 BayesianArrayStructure::BayesianArrayStructure(int length){
|
andrew@28
|
38 printf("BAYESIAN STURTUCRE CREATED LENGTH: %i\n", length);
|
andrew@28
|
39 //this constructor isnt called it seems
|
andrew@28
|
40 prior.createVector(length);
|
andrew@28
|
41 likelihood.createVector(length);
|
andrew@28
|
42 posterior.createVector(length);
|
andrew@28
|
43
|
andrew@28
|
44 lastEventTime = 0;
|
andrew@28
|
45
|
andrew@28
|
46
|
andrew@28
|
47 }
|
andrew@28
|
48
|
andrew@28
|
49
|
andrew@28
|
50
|
andrew@28
|
51 void BayesianArrayStructure::resetSize(int length){
|
andrew@28
|
52 printf("BAYESIAN STRUCTURE size is : %i\n", length);
|
andrew@28
|
53
|
andrew@28
|
54 prior.createVector(length);
|
andrew@28
|
55 likelihood.createVector(length);
|
andrew@28
|
56 posterior.createVector(length);
|
andrew@28
|
57
|
andrew@28
|
58 acceleration.createVector(length);
|
andrew@28
|
59
|
andrew@28
|
60 }
|
andrew@28
|
61
|
andrew@28
|
62
|
andrew@28
|
63
|
andrew@28
|
64 void BayesianArrayStructure::resetSpeedToOne(){
|
andrew@28
|
65 relativeSpeedPrior.zero();
|
andrew@28
|
66 relativeSpeedPosterior.zero();
|
andrew@28
|
67 relativeSpeedLikelihood.zero();
|
andrew@28
|
68
|
andrew@28
|
69
|
andrew@28
|
70 relativeSpeedPosterior.addGaussianShape(100, 20, 0.8);
|
andrew@28
|
71 relativeSpeedPosterior.renormalise();
|
andrew@28
|
72 relativeSpeedPosterior.getMaximum();
|
andrew@28
|
73
|
andrew@28
|
74 setSpeedPrior(speedPriorValue);
|
andrew@28
|
75 speedEstimate = speedPriorValue;
|
andrew@28
|
76
|
andrew@28
|
77 prior.zero();
|
andrew@28
|
78 posterior.zero();
|
andrew@28
|
79
|
andrew@28
|
80 posterior.addToIndex(0, 1);
|
andrew@28
|
81 posterior.renormalise();
|
andrew@28
|
82
|
andrew@28
|
83
|
andrew@28
|
84 //acceleration.addGaussianShape(2000, 20, 0.8);
|
andrew@28
|
85
|
andrew@28
|
86 }
|
andrew@28
|
87
|
andrew@28
|
88 void BayesianArrayStructure::setSpeedPrior(double f){
|
andrew@28
|
89 speedPriorValue = f;
|
andrew@28
|
90 int index = relativeSpeedPosterior.getRealTermsAsIndex(speedPriorValue);
|
andrew@28
|
91 relativeSpeedPosterior.zero();
|
andrew@28
|
92 relativeSpeedPosterior.addGaussianShape(index, priorWidth, 0.8);
|
andrew@28
|
93 relativeSpeedPosterior.renormalise();
|
andrew@28
|
94 relativeSpeedPosterior.getMaximum();
|
andrew@28
|
95 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@28
|
96 printf("BAYES STRUCTU ' SPEED PRIOR %f . index %i\n", speedPriorValue, index);
|
andrew@28
|
97
|
andrew@28
|
98 }
|
andrew@28
|
99
|
andrew@28
|
100 void BayesianArrayStructure::resetSpeedSize(int length){
|
andrew@28
|
101 printf("BAYESIAN SPEED size is : %i\n", length);
|
andrew@28
|
102
|
andrew@28
|
103 relativeSpeedPrior.createVector(length);
|
andrew@28
|
104 relativeSpeedLikelihood.createVector(length);
|
andrew@28
|
105 relativeSpeedPosterior.createVector(length);
|
andrew@28
|
106 tmpPosteriorForStorage.createVector(length);
|
andrew@28
|
107
|
andrew@28
|
108
|
andrew@28
|
109
|
andrew@28
|
110 }
|
andrew@28
|
111
|
andrew@28
|
112 void BayesianArrayStructure::setRelativeSpeedScalar(double f){
|
andrew@28
|
113 relativeSpeedPrior.scalar = f;
|
andrew@28
|
114 relativeSpeedPosterior.scalar = f;
|
andrew@28
|
115 relativeSpeedLikelihood.scalar = f;
|
andrew@28
|
116 }
|
andrew@28
|
117
|
andrew@28
|
118
|
andrew@28
|
119 void BayesianArrayStructure::setPositionDistributionScalar(double f){
|
andrew@28
|
120 if (f > 0){
|
andrew@28
|
121 prior.scalar = f;
|
andrew@28
|
122 posterior.scalar = f;
|
andrew@28
|
123 likelihood.scalar = f;
|
andrew@28
|
124 }
|
andrew@28
|
125 }
|
andrew@28
|
126
|
andrew@28
|
127 void BayesianArrayStructure::simpleExample(){
|
andrew@28
|
128 relativeSpeedPosterior.getMaximum();
|
andrew@28
|
129 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@28
|
130 }
|
andrew@28
|
131
|
andrew@28
|
132 void BayesianArrayStructure::copyPriorToPosterior(){
|
andrew@28
|
133
|
andrew@28
|
134 for (int i = 0;i < prior.arraySize;i++){
|
andrew@28
|
135 posterior.array[i] = prior.array[i];
|
andrew@28
|
136 }
|
andrew@28
|
137 }
|
andrew@28
|
138
|
andrew@28
|
139 void BayesianArrayStructure::setStartPlaying(){
|
andrew@28
|
140
|
andrew@28
|
141 lastEventTime = 0;
|
andrew@28
|
142 bestEstimate = 0;
|
andrew@28
|
143 lastBestEstimateUpdateTime = 0;
|
andrew@28
|
144 if (*realTimeMode)
|
andrew@28
|
145 lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
|
andrew@28
|
146 //cannot just be zero - offline bug
|
andrew@28
|
147 printf("start playing - best estimate %f\n", lastBestEstimateUpdateTime);
|
andrew@28
|
148
|
andrew@28
|
149 resetArrays();
|
andrew@28
|
150 }
|
andrew@28
|
151
|
andrew@28
|
152 void BayesianArrayStructure::resetArrays(){
|
andrew@28
|
153 //called when we start playing
|
andrew@28
|
154
|
andrew@28
|
155 prior.zero();
|
andrew@28
|
156 likelihood.zero();
|
andrew@28
|
157 posterior.zero();
|
andrew@28
|
158
|
andrew@28
|
159 updateCounter = 0;
|
andrew@28
|
160
|
andrew@31
|
161 posterior.offset = -1000;
|
andrew@28
|
162 setNewDistributionOffsets(0);
|
andrew@28
|
163
|
andrew@28
|
164 int zeroIndex = posterior.getRealTermsAsIndex(0);
|
andrew@28
|
165
|
andrew@28
|
166 posterior.addGaussianShape(zeroIndex, 500, 1);
|
andrew@28
|
167 // posterior.addToIndex(0, 1);
|
andrew@28
|
168 likelihood.addConstant(1);
|
andrew@28
|
169
|
andrew@28
|
170 updateCounter = 0;
|
andrew@28
|
171
|
andrew@28
|
172
|
andrew@28
|
173 printf("bayes reset arrays - best estimate %f\n", lastBestEstimateUpdateTime);
|
andrew@28
|
174
|
andrew@28
|
175 setSpeedPrior(speedPriorValue);
|
andrew@28
|
176 }
|
andrew@28
|
177
|
andrew@28
|
178
|
andrew@28
|
179 void BayesianArrayStructure::zeroArrays(){
|
andrew@28
|
180 prior.zero();
|
andrew@28
|
181 likelihood.zero();
|
andrew@28
|
182 posterior.zero();
|
andrew@28
|
183
|
andrew@28
|
184 relativeSpeedPrior.zero();
|
andrew@28
|
185 relativeSpeedPosterior.zero();
|
andrew@28
|
186 relativeSpeedLikelihood.zero();
|
andrew@28
|
187
|
andrew@28
|
188 }
|
andrew@28
|
189
|
andrew@28
|
190
|
andrew@28
|
191 void BayesianArrayStructure::updateTmpBestEstimate(const double& timeDifference){
|
andrew@28
|
192 //input is the time since the start of playing
|
andrew@28
|
193
|
andrew@28
|
194 // double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//lastBestEstimateUpdateTime;
|
andrew@28
|
195
|
andrew@28
|
196 tmpBestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDifference*relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
|
andrew@28
|
197 //
|
andrew@28
|
198 //printf("tmp best %f and best %f time diff %f posterior MAP %f at speed %f\n", tmpBestEstimate, bestEstimate, timeDifference, posterior.getIndexInRealTerms(posterior.MAPestimate), relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate));
|
andrew@28
|
199 //lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
|
andrew@28
|
200 }
|
andrew@28
|
201
|
andrew@28
|
202 void BayesianArrayStructure::updateBestEstimate(const double& timeDifference){
|
andrew@28
|
203 // double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//
|
andrew@28
|
204
|
andrew@28
|
205 double timeDiff = timeDifference;
|
andrew@28
|
206
|
andrew@28
|
207 //Using timedifferencfe here will make it go wrong. Is time since beginning of playing
|
andrew@28
|
208
|
andrew@28
|
209 if (*realTimeMode)
|
andrew@28
|
210 timeDiff = ofGetElapsedTimeMillis() - lastBestEstimateUpdateTime;
|
andrew@28
|
211
|
andrew@28
|
212 double speedEstimate;
|
andrew@28
|
213 if (usingIntegratedTempoEstimate)
|
andrew@28
|
214 speedEstimate = relativeSpeedPosterior.getIntegratedEstimate();
|
andrew@28
|
215 else
|
andrew@28
|
216 speedEstimate = relativeSpeedPosterior.MAPestimate;
|
andrew@28
|
217
|
andrew@28
|
218
|
andrew@28
|
219 speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(speedEstimate);
|
andrew@28
|
220 //relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate)
|
andrew@28
|
221 bestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*speedEstimate;
|
andrew@28
|
222
|
andrew@28
|
223 // bestEstimate = tmpBestEstimate;
|
andrew@28
|
224 }
|
andrew@28
|
225
|
andrew@28
|
226 void BayesianArrayStructure::calculatePosterior(){
|
andrew@28
|
227 //posterior.doProduct(prior, likelihood);
|
andrew@28
|
228
|
andrew@28
|
229 int i;
|
andrew@28
|
230 for (i = 0;i < posterior.length;i++){
|
andrew@28
|
231 posterior.array[i] = likelihood.array[i] * prior.array[i];
|
andrew@28
|
232 }
|
andrew@28
|
233
|
andrew@28
|
234
|
andrew@28
|
235 posterior.renormalise();
|
andrew@28
|
236
|
andrew@28
|
237
|
andrew@28
|
238
|
andrew@28
|
239
|
andrew@28
|
240 }
|
andrew@28
|
241
|
andrew@28
|
242
|
andrew@28
|
243
|
andrew@28
|
244
|
andrew@28
|
245 void BayesianArrayStructure::setNewDistributionOffsets(const double& newOffset){
|
andrew@28
|
246 prior.offset = newOffset;
|
andrew@28
|
247 likelihood.offset = newOffset;
|
andrew@28
|
248 //posterior.offset = newOffset;
|
andrew@28
|
249 }
|
andrew@28
|
250
|
andrew@28
|
251
|
andrew@28
|
252 void BayesianArrayStructure::crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference){
|
andrew@28
|
253 //set the cutoff for offset of position first! XXX
|
andrew@28
|
254
|
andrew@28
|
255 // printf("time difference %f, ", timeDifference);
|
andrew@28
|
256
|
andrew@28
|
257 double timeDifferenceInPositionVectorUnits = timeDifference / prior.scalar;
|
andrew@28
|
258
|
andrew@28
|
259
|
andrew@28
|
260 prior.zero();//kill prior
|
andrew@28
|
261 calculateNewPriorOffset(timeDifference);//set new prior offset here
|
andrew@28
|
262
|
andrew@28
|
263 if (timeDifferenceInPositionVectorUnits > crossUpdateTimeThreshold)
|
andrew@28
|
264 complexCrossUpdate(timeDifferenceInPositionVectorUnits);
|
andrew@28
|
265 else
|
andrew@28
|
266 translateByMaximumSpeed(timeDifferenceInPositionVectorUnits);
|
andrew@28
|
267
|
andrew@28
|
268
|
andrew@28
|
269 updateCounter++;
|
andrew@28
|
270 prior.renormalise();
|
andrew@28
|
271
|
andrew@28
|
272 }
|
andrew@28
|
273
|
andrew@28
|
274 void BayesianArrayStructure::complexCrossUpdate(const double& timeDifferenceInPositionVectorUnits){
|
andrew@28
|
275 int distanceMoved, newPriorIndex;
|
andrew@28
|
276
|
andrew@28
|
277 double speedValue = relativeSpeedPosterior.offset;
|
andrew@28
|
278
|
andrew@28
|
279 for (int i = 0;i < relativeSpeedPosterior.arraySize;i++){
|
andrew@28
|
280
|
andrew@28
|
281 // double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
|
andrew@28
|
282
|
andrew@28
|
283 //so we have moved
|
andrew@28
|
284 distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
|
andrew@28
|
285
|
andrew@28
|
286 if (relativeSpeedPosterior.array[i] != 0){
|
andrew@28
|
287 double speedContribution = relativeSpeedPosterior.array[i];
|
andrew@28
|
288 // printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits);
|
andrew@28
|
289
|
andrew@28
|
290 newPriorIndex = posterior.offset - prior.offset + distanceMoved;
|
andrew@28
|
291
|
andrew@28
|
292 for (int postIndex = 0;postIndex < posterior.arraySize;postIndex++){
|
andrew@28
|
293 //old posterior contributing to new prior
|
andrew@28
|
294 // newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
|
andrew@28
|
295
|
andrew@28
|
296 if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
|
andrew@28
|
297 prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
|
andrew@28
|
298 }
|
andrew@28
|
299
|
andrew@28
|
300 newPriorIndex++;//optimised code - the commented line above explains how this works
|
andrew@28
|
301 }//end for
|
andrew@28
|
302
|
andrew@28
|
303
|
andrew@28
|
304 }//if not zero
|
andrew@28
|
305 speedValue += relativeSpeedPosterior.scalar;
|
andrew@28
|
306 //optimised line
|
andrew@28
|
307 //as we wanted:
|
andrew@28
|
308 // double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
|
andrew@28
|
309 }//end speed
|
andrew@28
|
310 }
|
andrew@28
|
311
|
andrew@28
|
312
|
andrew@28
|
313
|
andrew@28
|
314 void BayesianArrayStructure::translateByMaximumSpeed(const double& timeDifferenceInPositionVectorUnits){
|
andrew@28
|
315
|
andrew@28
|
316 int distanceMoved, newPriorIndex;
|
andrew@28
|
317
|
andrew@28
|
318 double speedValue = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
|
andrew@28
|
319 //so for scalar 0.01, 50 -> speed value of 0.5
|
andrew@28
|
320 double speedContribution = relativeSpeedPosterior.array[relativeSpeedPosterior.integratedEstimate];
|
andrew@28
|
321 //so we have moved
|
andrew@28
|
322 distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
|
andrew@28
|
323 // printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits);
|
andrew@28
|
324
|
andrew@28
|
325 for (int postIndex = 0;postIndex < posterior.arraySize;postIndex++){
|
andrew@28
|
326 //old posterior contributing to new prior
|
andrew@28
|
327 newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
|
andrew@28
|
328 if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
|
andrew@28
|
329 prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
|
andrew@28
|
330 }
|
andrew@28
|
331
|
andrew@28
|
332 }
|
andrew@28
|
333
|
andrew@28
|
334 }
|
andrew@28
|
335
|
andrew@28
|
336 void BayesianArrayStructure::addGaussianNoiseToSpeedPosterior(const double& std_dev){
|
andrew@28
|
337 tmpPosteriorForStorage.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@28
|
338
|
andrew@28
|
339 for (int i = 0;i < relativeSpeedPosterior.length;i++){
|
andrew@28
|
340 tmpPosteriorForStorage.addGaussianShape(i, std_dev, relativeSpeedPosterior.array[i]);
|
andrew@28
|
341 }
|
andrew@28
|
342
|
andrew@28
|
343 tmpPosteriorForStorage.renormalise();
|
andrew@28
|
344
|
andrew@28
|
345 relativeSpeedPosterior.copyFromDynamicVector(tmpPosteriorForStorage);
|
andrew@28
|
346 }
|
andrew@28
|
347
|
andrew@28
|
348
|
andrew@28
|
349 void BayesianArrayStructure::addTriangularNoiseToSpeedPosterior(const double& std_dev){
|
andrew@28
|
350 tmpPosteriorForStorage.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@28
|
351
|
andrew@28
|
352 for (int i = 0;i < relativeSpeedPosterior.length;i++){
|
andrew@28
|
353 //adding a linear amount depending on distance
|
andrew@28
|
354 tmpPosteriorForStorage.addTriangularShape(i, std_dev*2.0, relativeSpeedPosterior.array[i]);
|
andrew@28
|
355 }
|
andrew@28
|
356
|
andrew@28
|
357 tmpPosteriorForStorage.renormalise();
|
andrew@28
|
358
|
andrew@28
|
359 relativeSpeedPosterior.copyFromDynamicVector(tmpPosteriorForStorage);
|
andrew@28
|
360 }
|
andrew@28
|
361
|
andrew@28
|
362 void BayesianArrayStructure::calculateNewPriorOffset(const double& timeDifference){
|
andrew@28
|
363
|
andrew@28
|
364 double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
|
andrew@28
|
365 // printf("Maxspeed is %f\n", maxSpeed);
|
andrew@28
|
366
|
andrew@28
|
367 double priorMax = posterior.getMaximum();
|
andrew@28
|
368 double distanceTravelled = maxSpeed * (timeDifference / prior.scalar);
|
andrew@28
|
369 double newMaxLocation = posterior.MAPestimate + distanceTravelled;
|
andrew@28
|
370 // printf("MAP: %i, tim df %f, distance %f, new location %f\n", posterior.MAPestimate, timeDifference, distanceTravelled, newMaxLocation);
|
andrew@28
|
371
|
andrew@28
|
372 }
|
andrew@28
|
373
|
andrew@28
|
374
|
andrew@28
|
375 void BayesianArrayStructure::decaySpeedDistribution(double timeDifference){
|
andrew@28
|
376
|
andrew@28
|
377 // commented for the moment
|
andrew@28
|
378 double relativeAmount = max(1.0, timeDifference/1000.);
|
andrew@28
|
379 // printf("decay %f around %i \n", timeDifference, relativeSpeedPosterior.MAPestimate);
|
andrew@28
|
380 relativeAmount *= speedDecayAmount;
|
andrew@28
|
381 relativeSpeedPosterior.renormalise();
|
andrew@31
|
382 relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, relativeAmount);
|
andrew@28
|
383
|
andrew@28
|
384 relativeSpeedPosterior.renormalise();
|
andrew@28
|
385 double newMax = relativeSpeedPosterior.getMaximum();
|
andrew@28
|
386
|
andrew@28
|
387 //old code
|
andrew@28
|
388 // relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, 10);
|
andrew@28
|
389 //relativeSpeedPosterior.addConstant(1);
|
andrew@28
|
390
|
andrew@28
|
391 /*
|
andrew@28
|
392 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@28
|
393 relativeSpeedLikelihood.zero();
|
andrew@28
|
394 relativeSpeedLikelihood.addConstant(0.2);
|
andrew@28
|
395 relativeSpeedLikelihood.addGaussianShape(relativeSpeedPosterior.maximumValue, speedDecayWidth, relativeAmount);
|
andrew@28
|
396 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
|
andrew@28
|
397 relativeSpeedPosterior.renormalise();
|
andrew@28
|
398 */
|
andrew@28
|
399
|
andrew@28
|
400
|
andrew@28
|
401
|
andrew@28
|
402 }
|
andrew@28
|
403
|
andrew@28
|
404 void BayesianArrayStructure::setLikelihoodToConstant(){
|
andrew@28
|
405 //set new likelihood
|
andrew@28
|
406 relativeSpeedLikelihood.zero();
|
andrew@28
|
407 relativeSpeedLikelihood.addConstant(speedLikelihoodNoise);
|
andrew@28
|
408 }
|
andrew@28
|
409
|
andrew@28
|
410
|
andrew@28
|
411 void BayesianArrayStructure::updateTempoLikelihood(const double& speedRatio, const double& matchFactor){
|
andrew@28
|
412
|
andrew@28
|
413 //speedratio is speed of played relative to the recording
|
andrew@28
|
414
|
andrew@28
|
415 double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
|
andrew@28
|
416 // printf("index of likelihood would be %f for ratio %f\n", index, speedRatio);
|
andrew@28
|
417 if (index >= 0 && index < relativeSpeedPrior.length){
|
andrew@28
|
418 relativeSpeedLikelihood.addGaussianShape(index , relativeSpeedLikelihoodStdDev, matchFactor);
|
andrew@28
|
419 }
|
andrew@28
|
420 }
|
andrew@28
|
421
|
andrew@28
|
422
|
andrew@28
|
423
|
andrew@28
|
424 void BayesianArrayStructure::updateTempoDistribution(){
|
andrew@28
|
425
|
andrew@28
|
426 //copy posterior to prior
|
andrew@28
|
427 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@28
|
428
|
andrew@28
|
429 //update
|
andrew@28
|
430 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
|
andrew@28
|
431
|
andrew@28
|
432 //normalise
|
andrew@28
|
433 relativeSpeedPosterior.renormalise();
|
andrew@28
|
434
|
andrew@28
|
435 relativeSpeedPosterior.getMaximum();
|
andrew@28
|
436
|
andrew@31
|
437 // relativeSpeedPosterior.updateIntegratedEstimate();
|
andrew@31
|
438 relativeSpeedPosterior.updateLimitedIntegratedEstimate();
|
andrew@31
|
439
|
andrew@28
|
440 speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
|
andrew@28
|
441 }
|
andrew@28
|
442
|
andrew@28
|
443
|
andrew@28
|
444 void BayesianArrayStructure::calculateTempoUpdate(){
|
andrew@28
|
445 //copy posterior to prior
|
andrew@28
|
446 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@28
|
447
|
andrew@28
|
448 //update
|
andrew@28
|
449 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
|
andrew@28
|
450
|
andrew@28
|
451 //normalise
|
andrew@28
|
452 relativeSpeedPosterior.renormalise();
|
andrew@28
|
453
|
andrew@28
|
454 relativeSpeedPosterior.getMaximum();
|
andrew@28
|
455
|
andrew@28
|
456 }
|
andrew@28
|
457
|
andrew@28
|
458
|
andrew@28
|
459 void BayesianArrayStructure::drawArrays(){
|
andrew@28
|
460
|
andrew@28
|
461 //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
|
andrew@28
|
462 //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
|
andrew@28
|
463
|
andrew@28
|
464 int displaySize = prior.arraySize;
|
andrew@28
|
465 ofSetColor(0,0,255);
|
andrew@28
|
466 prior.drawVector(0, displaySize);
|
andrew@28
|
467 ofSetColor(0,255,0);
|
andrew@28
|
468 likelihood.drawVector(0, displaySize);
|
andrew@28
|
469 ofSetColor(255,0,255);
|
andrew@28
|
470 posterior.drawVector(0, displaySize);
|
andrew@28
|
471
|
andrew@28
|
472
|
andrew@28
|
473
|
andrew@28
|
474 }
|
andrew@28
|
475
|
andrew@28
|
476
|
andrew@28
|
477 void BayesianArrayStructure::drawTempoArrays(){
|
andrew@28
|
478 ofSetColor(0,0,255);
|
andrew@28
|
479 // relativeSpeedPrior.drawVector(0, relativeSpeedPrior.arraySize);
|
andrew@28
|
480
|
andrew@28
|
481 ofSetColor(0,150,255);
|
andrew@28
|
482 relativeSpeedLikelihood.drawVector(0, relativeSpeedLikelihood.arraySize);
|
andrew@28
|
483
|
andrew@28
|
484 // relativeSpeedLikelihood.drawConstrainedVector(0, 199, 0, 1000);// relativeSpeedLikelihood.arraySize);
|
andrew@28
|
485 ofSetColor(255,0,0);
|
andrew@28
|
486 relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize);
|
andrew@28
|
487
|
andrew@28
|
488 // ofSetColor(0,0,255);
|
andrew@28
|
489 // tmpPosteriorForStorage.drawVector(0, tmpPosteriorForStorage.arraySize);
|
andrew@28
|
490
|
andrew@28
|
491 ofSetColor(255,255, 255);
|
andrew@28
|
492 ofLine(screenWidth/2, 0, screenWidth/2, ofGetHeight());//middle of screen
|
andrew@28
|
493
|
andrew@28
|
494 ofSetColor(25, 0, 250);
|
andrew@28
|
495 double fractionOfScreen = ((double)relativeSpeedPosterior.integratedEstimate / relativeSpeedPosterior.length);
|
andrew@28
|
496 ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
|
andrew@28
|
497
|
andrew@28
|
498 ofSetColor(255, 0, 20);
|
andrew@28
|
499 fractionOfScreen = ((double)relativeSpeedPosterior.MAPestimate / relativeSpeedPosterior.length);
|
andrew@28
|
500 ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
|
andrew@28
|
501
|
andrew@28
|
502
|
andrew@28
|
503 }
|
andrew@28
|
504
|
andrew@28
|
505
|
andrew@28
|
506 void BayesianArrayStructure::drawArraysRelativeToTimeframe(const double& startTimeMillis, const double& endTimeMillis){
|
andrew@28
|
507
|
andrew@28
|
508 screenWidth = ofGetWidth();
|
andrew@28
|
509
|
andrew@28
|
510 int startArrayIndex = 0;
|
andrew@28
|
511
|
andrew@28
|
512 if (prior.getIndexInRealTerms(prior.arraySize-1) > startTimeMillis){
|
andrew@28
|
513 //i.e. the array is on the page
|
andrew@28
|
514
|
andrew@28
|
515 while (prior.getIndexInRealTerms(startArrayIndex) < startTimeMillis){
|
andrew@28
|
516 startArrayIndex++;
|
andrew@28
|
517 }
|
andrew@28
|
518 int endArrayIndex = prior.arraySize-1;
|
andrew@28
|
519 //could find constraints here
|
andrew@28
|
520 if (prior.getIndexInRealTerms(prior.arraySize-1) > endTimeMillis)
|
andrew@28
|
521 endArrayIndex = (floor)((endTimeMillis - prior.offset)/prior.scalar);
|
andrew@28
|
522
|
andrew@28
|
523 //so we need to figure where start and end array are on screen
|
andrew@28
|
524 int startScreenPosition, endScreenPosition;
|
andrew@28
|
525 double screenWidthMillis = endTimeMillis - startTimeMillis;
|
andrew@28
|
526
|
andrew@28
|
527 startScreenPosition = (prior.getIndexInRealTerms(startArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
|
andrew@28
|
528 endScreenPosition = (double)(prior.getIndexInRealTerms(endArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
|
andrew@28
|
529
|
andrew@28
|
530 ofSetColor(0,0,100);
|
andrew@28
|
531 string relativeString = " offset "+ofToString(prior.offset, 1);//starttimes("+ofToString(startTimeMillis)+", "+ofToString(endTimeMillis);
|
andrew@28
|
532 relativeString += ": index "+ofToString(startArrayIndex)+" , "+ofToString(endArrayIndex)+" [";
|
andrew@28
|
533 // relativeString += ofToString(prior.getIndexInRealTerms(endArrayIndex), 3)+"] (sc-width:"+ofToString(screenWidthMillis, 1)+") ";
|
andrew@28
|
534 relativeString += " mapped to screen "+ofToString(startScreenPosition)+" , "+ofToString(endScreenPosition);
|
andrew@28
|
535 // ofDrawBitmapString(relativeString, 100, 180);
|
andrew@28
|
536
|
andrew@28
|
537
|
andrew@28
|
538
|
andrew@28
|
539 ofSetColor(100,100,100);//255, 255, 0);
|
andrew@28
|
540 likelihood.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
|
andrew@28
|
541
|
andrew@28
|
542 // ofSetColor(0,0,200);
|
andrew@28
|
543 ofSetColor(170,170,170);//00,200);
|
andrew@28
|
544 prior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
|
andrew@28
|
545
|
andrew@28
|
546 ofSetColor(0,0,150);
|
andrew@28
|
547 // ofSetColor(200, 0, 0);
|
andrew@28
|
548 posterior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
|
andrew@28
|
549
|
andrew@28
|
550
|
andrew@28
|
551 // ofSetColor(0, 200, 255);
|
andrew@28
|
552 // acceleration.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
|
andrew@28
|
553
|
andrew@28
|
554
|
andrew@28
|
555 }
|
andrew@28
|
556
|
andrew@28
|
557 }
|
andrew@28
|
558
|
andrew@28
|
559
|
andrew@28
|
560 /*
|
andrew@28
|
561
|
andrew@28
|
562 void BayesianArrayStructure::updateTempoDistribution(const double& speedRatio, const double& matchFactor){
|
andrew@28
|
563 //speedratio is speed of played relative to the recording
|
andrew@28
|
564
|
andrew@28
|
565 double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
|
andrew@28
|
566 // printf("\nindex of likelihood would be %f\n", index);
|
andrew@28
|
567 if (index >= 0 && index < relativeSpeedPrior.length){
|
andrew@28
|
568 //then we can do update
|
andrew@28
|
569
|
andrew@28
|
570 //set new likelihood
|
andrew@28
|
571 relativeSpeedLikelihood.zero();
|
andrew@28
|
572 relativeSpeedLikelihood.addConstant(speedLikelihoodNoise);
|
andrew@28
|
573
|
andrew@28
|
574 relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5*matchFactor);
|
andrew@28
|
575
|
andrew@28
|
576
|
andrew@28
|
577 //copy posterior to prior
|
andrew@28
|
578 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@28
|
579
|
andrew@28
|
580 //update
|
andrew@28
|
581 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
|
andrew@28
|
582
|
andrew@28
|
583 //normalise
|
andrew@28
|
584 relativeSpeedPosterior.renormalise();
|
andrew@28
|
585
|
andrew@28
|
586 relativeSpeedPosterior.getMaximum();
|
andrew@28
|
587 }//end if within range
|
andrew@28
|
588
|
andrew@28
|
589
|
andrew@28
|
590 }
|
andrew@28
|
591
|
andrew@28
|
592 */ |