comparison bayesianArraySrc/BayesianArrayStructure.cpp @ 0:c4f9e49226eb

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