annotate src/BayesianArrayStructure.cpp @ 1:1a32ce016bb9

Changed bestEstimate timing to work via time sent from Max not the elapsed time. This had caused some problems, but this version now working surprisingly well on MIDI files with variable timing.
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Thu, 18 Aug 2011 23:27:42 +0100
parents b299a65a3ad0
children 5581023e0de4
rev   line source
andrew@0 1 /*
andrew@0 2 * BayesianArrayStructure.cpp
andrew@0 3 * midiCannamReader
andrew@0 4 *
andrew@0 5 * Created by Andrew on 17/07/2011.
andrew@0 6 * Copyright 2011 QMUL. All rights reserved.
andrew@0 7 *
andrew@0 8 */
andrew@0 9
andrew@0 10 #include "BayesianArrayStructure.h"
andrew@0 11
andrew@0 12 BayesianArrayStructure::BayesianArrayStructure(){
andrew@0 13 printf("Bayesian structure: DeFault constructor called");
andrew@0 14
andrew@0 15 prior.createVector(1);
andrew@0 16 likelihood.createVector(1);
andrew@0 17 posterior.createVector(1);
andrew@0 18
andrew@0 19
andrew@0 20 tmpPrior.createVector(240);
andrew@0 21 tmpPrior.addGaussianShape(100, 40, 1);
andrew@0 22 tmpPrior.addGaussianShape(200, 10, 0.2);
andrew@0 23 tmpPrior.translateDistribution(20);
andrew@0 24
andrew@0 25 lastEventTime = ofGetElapsedTimeMillis();
andrew@0 26
andrew@0 27 speedDecayWidth = 20;
andrew@0 28 speedDecayAmount = 10;
andrew@0 29 }
andrew@0 30
andrew@0 31 BayesianArrayStructure::BayesianArrayStructure(int length){
andrew@0 32 printf("BAYESIAN STURTUCRE CREATED LENGTH: %i\n", length);
andrew@0 33 //this constructor isnt called it seems
andrew@0 34 prior.createVector(length);
andrew@0 35 likelihood.createVector(length);
andrew@0 36 posterior.createVector(length);
andrew@0 37
andrew@0 38 }
andrew@0 39
andrew@0 40
andrew@0 41
andrew@0 42 void BayesianArrayStructure::resetSize(int length){
andrew@0 43 printf("BAYESIAN STRUCTURE size is : %i\n", length);
andrew@0 44
andrew@0 45 prior.createVector(length);
andrew@0 46 likelihood.createVector(length);
andrew@0 47 posterior.createVector(length);
andrew@0 48
andrew@0 49 acceleration.createVector(length);
andrew@0 50
andrew@0 51 }
andrew@0 52
andrew@0 53
andrew@0 54
andrew@0 55 void BayesianArrayStructure::resetSpeedToOne(){
andrew@0 56 relativeSpeedPrior.zero();
andrew@0 57 relativeSpeedPosterior.zero();
andrew@0 58 relativeSpeedLikelihood.zero();
andrew@0 59
andrew@0 60 relativeSpeedPosterior.addGaussianShape(40, 5, 0.6);
andrew@0 61
andrew@0 62 relativeSpeedPosterior.addGaussianShape(100, 5, 0.8);
andrew@0 63 relativeSpeedPosterior.renormalise();
andrew@0 64 relativeSpeedPosterior.getMaximum();
andrew@0 65
andrew@0 66 acceleration.addGaussianShape(2000, 20, 0.8);
andrew@0 67
andrew@0 68 }
andrew@0 69
andrew@0 70 void BayesianArrayStructure::resetSpeedSize(int length){
andrew@0 71 printf("BAYESIAN SPEED size is : %i\n", length);
andrew@0 72
andrew@0 73 relativeSpeedPrior.createVector(length);
andrew@0 74 relativeSpeedLikelihood.createVector(length);
andrew@0 75 relativeSpeedPosterior.createVector(length);
andrew@0 76
andrew@0 77
andrew@0 78
andrew@0 79 }
andrew@0 80 void BayesianArrayStructure::setRelativeSpeedScalar(double f){
andrew@0 81 relativeSpeedPrior.scalar = f;
andrew@0 82 relativeSpeedPosterior.scalar = f;
andrew@0 83 relativeSpeedLikelihood.scalar = f;
andrew@0 84 }
andrew@0 85
andrew@0 86 void BayesianArrayStructure::simpleExample(){
andrew@0 87 //simple example
andrew@0 88 prior.addGaussianShape(50, 10, 1);
andrew@0 89 prior.addGaussianShape(150, 30, 0.3);
andrew@0 90 prior.addGaussianShape(250, 30, 0.2);
andrew@0 91
andrew@0 92 likelihood.addGaussianShape(90, 20, 0.6);
andrew@0 93 likelihood.addConstant(0.02);
andrew@0 94 posterior.doProduct(prior, likelihood);
andrew@0 95
andrew@0 96 // relativeSpeedPosterior.addToIndex(100, 1);
andrew@0 97 // relativeSpeedPosterior.addToIndex(40, 0.7);
andrew@0 98 relativeSpeedPosterior.addGaussianShape(100, 20, 1);
andrew@0 99 // relativeSpeedPosterior.addGaussianShape(10, 2, 0.5);
andrew@0 100 relativeSpeedPosterior.getMaximum();
andrew@0 101
andrew@0 102 }
andrew@0 103
andrew@0 104 void BayesianArrayStructure::copyPriorToPosterior(){
andrew@0 105
andrew@0 106 for (int i = 0;i < prior.arraySize;i++){
andrew@0 107 posterior.array[i] = prior.array[i];
andrew@0 108 }
andrew@0 109 }
andrew@0 110
andrew@0 111 void BayesianArrayStructure::resetArrays(){
andrew@0 112 prior.zero();
andrew@0 113 likelihood.zero();
andrew@0 114 prior.addGaussianShape(0, 80, 1);
andrew@0 115 likelihood.addConstant(1);
andrew@0 116 posterior.zero();
andrew@0 117 posterior.addGaussianShape(0, 60, 1);
andrew@0 118 setNewDistributionOffsets(0);
andrew@0 119 bestEstimate = 0;
andrew@0 120 // lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
andrew@0 121
andrew@0 122 }
andrew@0 123
andrew@0 124 void BayesianArrayStructure::updateBestEstimate(){
andrew@0 125 double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//lastBestEstimateUpdateTime;
andrew@0 126
andrew@0 127 bestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate);
andrew@0 128 //
andrew@0 129 //lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
andrew@0 130 }
andrew@0 131
andrew@0 132 void BayesianArrayStructure::calculatePosterior(){
andrew@0 133 posterior.doProduct(prior, likelihood);
andrew@0 134 posterior.renormalise();
andrew@0 135
andrew@0 136 /*
andrew@0 137 int i;
andrew@0 138 for (i = 0;i < prior.length;i++){
andrew@0 139 // printf("priori [%i] is %f\n", i, prior[i]);
andrew@0 140 *(posterior+i) = *(prior+i);
andrew@0 141 // posterior[i] = likelihood[i] * prior[i];
andrew@0 142 }
andrew@0 143 */
andrew@0 144
andrew@0 145
andrew@0 146 }
andrew@0 147
andrew@0 148
andrew@0 149
andrew@0 150
andrew@0 151 void BayesianArrayStructure::setNewDistributionOffsets(const double& newOffset){
andrew@0 152 prior.offset = newOffset;
andrew@0 153 likelihood.offset = newOffset;
andrew@0 154 // posterior.offset = newOffset;
andrew@0 155 }
andrew@0 156
andrew@0 157
andrew@0 158 void BayesianArrayStructure::crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference){
andrew@0 159 //set the cutoff for offset of position first! XXX
andrew@0 160
andrew@0 161 // printf("time difference %f, ", timeDifference);
andrew@0 162
andrew@0 163 double timeDifferenceInPositionVectorUnits = timeDifference / prior.scalar;
andrew@0 164
andrew@0 165 prior.zero();//kill prior
andrew@0 166 calculateNewPriorOffset(timeDifference);//set new prior offset here
andrew@0 167
andrew@0 168 for (int i = 0;i < speed.arraySize;i++){
andrew@0 169 // printf("[%i] %f\n", i, speed.array[i]);
andrew@0 170 //set speed
andrew@0 171 double speedValue = speed.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
andrew@0 172
andrew@0 173 //so we have moved
andrew@0 174 int distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
andrew@0 175
andrew@0 176 if (speed.array[i] != 0){
andrew@0 177
andrew@0 178 // printf("speed [%i] gives %f moved %i\n", i, speedValue, distanceMoved);
andrew@0 179
andrew@0 180 for (int postIndex = 0;postIndex < position.arraySize;postIndex++){
andrew@0 181 //old posterior contributing to new prior
andrew@0 182 int newPriorIndex = postIndex + position.offset - prior.offset + distanceMoved;
andrew@0 183 if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
andrew@0 184 prior.addToIndex(newPriorIndex, position.array[postIndex]*speed.array[i]);
andrew@0 185 // printf("adding [%i] : %f\n", newPriorIndex, posterior.array[postIndex]*speed.array[i]);
andrew@0 186 }
andrew@0 187
andrew@0 188 }
andrew@0 189
andrew@0 190 }//if not zero
andrew@0 191 }//end speed
andrew@0 192
andrew@0 193 prior.renormalise();
andrew@0 194
andrew@0 195 }
andrew@0 196
andrew@0 197 void BayesianArrayStructure::calculateNewPriorOffset(const double& timeDifference){
andrew@0 198
andrew@0 199 double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate);
andrew@0 200 // printf("Maxspeed is %f\n", maxSpeed);
andrew@0 201
andrew@0 202 double priorMax = posterior.getMaximum();
andrew@0 203 double distanceTravelled = maxSpeed * (timeDifference / prior.scalar);
andrew@0 204 double newMaxLocation = posterior.MAPestimate + distanceTravelled;
andrew@0 205 // printf("MAP: %i, tim df %f, distance %f, new location %f\n", posterior.MAPestimate, timeDifference, distanceTravelled, newMaxLocation);
andrew@0 206
andrew@0 207 }
andrew@0 208
andrew@0 209
andrew@0 210 void BayesianArrayStructure::decaySpeedDistribution(double timeDifference){
andrew@0 211
andrew@0 212 // commented for the moment
andrew@0 213 double relativeAmount = max(1.0, timeDifference/1000.);
andrew@0 214 // printf("decay %f around %i \n", timeDifference, relativeSpeedPosterior.MAPestimate);
andrew@0 215 relativeAmount *= speedDecayAmount;
andrew@0 216 relativeSpeedPosterior.renormalise();
andrew@0 217 relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, relativeAmount);
andrew@0 218
andrew@0 219 relativeSpeedPosterior.renormalise();
andrew@0 220 double newMax = relativeSpeedPosterior.getMaximum();
andrew@0 221
andrew@0 222 //old code
andrew@0 223 // relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, 10);
andrew@0 224 //relativeSpeedPosterior.addConstant(1);
andrew@0 225
andrew@0 226 /*
andrew@0 227 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 228 relativeSpeedLikelihood.zero();
andrew@0 229 relativeSpeedLikelihood.addConstant(0.2);
andrew@0 230 relativeSpeedLikelihood.addGaussianShape(relativeSpeedPosterior.maximumValue, speedDecayWidth, relativeAmount);
andrew@0 231 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
andrew@0 232 relativeSpeedPosterior.renormalise();
andrew@0 233 */
andrew@0 234
andrew@0 235
andrew@0 236
andrew@0 237 }
andrew@0 238
andrew@0 239 void BayesianArrayStructure::updateTempoDistribution(const double& speedRatio, const double& matchFactor){
andrew@0 240 //speedratio is speed of played relative to the recording
andrew@0 241
andrew@0 242 double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
andrew@0 243 // printf("\nindex of likelihood would be %f\n", index);
andrew@0 244 if (index >= 0 && index < relativeSpeedPrior.length){
andrew@0 245 //then we can do update
andrew@0 246
andrew@0 247 //set new likelihood
andrew@0 248 relativeSpeedLikelihood.zero();
andrew@1 249 relativeSpeedLikelihood.addConstant(0.05);
andrew@0 250
andrew@0 251 relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5*matchFactor);
andrew@0 252
andrew@0 253
andrew@0 254 //copy posterior to prior
andrew@0 255 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 256
andrew@0 257 //update
andrew@0 258 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
andrew@0 259
andrew@0 260 //normalise
andrew@0 261 relativeSpeedPosterior.renormalise();
andrew@0 262
andrew@0 263 relativeSpeedPosterior.getMaximum();
andrew@0 264 }//end if within range
andrew@0 265
andrew@0 266
andrew@0 267 }
andrew@0 268
andrew@0 269
andrew@0 270 void BayesianArrayStructure::setFlatTempoLikelihood(){ //set new likelihood
andrew@0 271 relativeSpeedLikelihood.zero();
andrew@0 272 relativeSpeedLikelihood.addConstant(0.3);
andrew@0 273 }
andrew@0 274
andrew@0 275 void BayesianArrayStructure::updateTempoLikelihood(const double& speedRatio, const double& matchFactor){
andrew@0 276
andrew@0 277 double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
andrew@0 278
andrew@0 279 if (index >= 0 && index < relativeSpeedPrior.length){
andrew@0 280 relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5);//*matchFactor);
andrew@0 281 }
andrew@0 282 }
andrew@0 283
andrew@0 284
andrew@0 285 void BayesianArrayStructure::calculateTempoUpdate(){
andrew@0 286 //copy posterior to prior
andrew@0 287 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 288
andrew@0 289 //update
andrew@0 290 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
andrew@0 291
andrew@0 292 //normalise
andrew@0 293 relativeSpeedPosterior.renormalise();
andrew@0 294
andrew@0 295 relativeSpeedPosterior.getMaximum();
andrew@0 296
andrew@0 297 }
andrew@0 298
andrew@0 299
andrew@0 300 void BayesianArrayStructure::drawArrays(){
andrew@0 301
andrew@0 302 //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
andrew@0 303 //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
andrew@0 304
andrew@0 305 int displaySize = prior.arraySize;
andrew@0 306 ofSetColor(255,0,0);
andrew@0 307 prior.drawVector(0, displaySize);
andrew@0 308 ofSetColor(0,255,0);
andrew@0 309 likelihood.drawVector(0, displaySize);
andrew@0 310 ofSetColor(0,0,255);
andrew@0 311 posterior.drawVector(0, displaySize);
andrew@0 312 ofSetColor(255,255,0);
andrew@0 313 relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize);
andrew@0 314
andrew@0 315 // ofSetColor(255,255,255);
andrew@0 316 // tmpPrior.drawVector(0,300);
andrew@0 317
andrew@0 318 }
andrew@0 319
andrew@0 320
andrew@0 321 void BayesianArrayStructure::drawTempoArrays(){
andrew@0 322 ofSetColor(0,255,255);
andrew@0 323 relativeSpeedPrior.drawVector(0, relativeSpeedPrior.arraySize);
andrew@0 324
andrew@0 325 ofSetColor(255,0,255);
andrew@0 326 relativeSpeedLikelihood.drawVector(0, relativeSpeedLikelihood.arraySize);
andrew@0 327
andrew@0 328 ofSetColor(255,255,0);
andrew@0 329 relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize);
andrew@0 330
andrew@0 331 ofSetColor(255,255, 255);
andrew@0 332 ofLine(screenWidth/2, 0, screenWidth/2, ofGetHeight());//middle of screen
andrew@0 333
andrew@0 334 ofSetColor(0, 255, 0);
andrew@0 335 double fractionOfScreen = ((double)relativeSpeedPosterior.MAPestimate / relativeSpeedPosterior.length);
andrew@0 336 ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
andrew@0 337 }
andrew@0 338
andrew@0 339
andrew@0 340 void BayesianArrayStructure::drawArraysRelativeToTimeframe(const double& startTimeMillis, const double& endTimeMillis){
andrew@0 341
andrew@0 342 screenWidth = ofGetWidth();
andrew@0 343
andrew@0 344 int startArrayIndex = 0;
andrew@0 345
andrew@0 346 if (prior.getIndexInRealTerms(prior.arraySize-1) > startTimeMillis){
andrew@0 347 //i.e. the array is on the page
andrew@0 348
andrew@0 349 while (prior.getIndexInRealTerms(startArrayIndex) < startTimeMillis){
andrew@0 350 startArrayIndex++;
andrew@0 351 }
andrew@0 352 int endArrayIndex = prior.arraySize-1;
andrew@0 353 //could find constraints here
andrew@0 354 if (prior.getIndexInRealTerms(prior.arraySize-1) > endTimeMillis)
andrew@0 355 endArrayIndex = (floor)((endTimeMillis - prior.offset)/prior.scalar);
andrew@0 356
andrew@0 357 //so we need to figure where start and end array are on screen
andrew@0 358 int startScreenPosition, endScreenPosition;
andrew@0 359 double screenWidthMillis = endTimeMillis - startTimeMillis;
andrew@0 360
andrew@0 361 startScreenPosition = (prior.getIndexInRealTerms(startArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
andrew@0 362 endScreenPosition = (double)(prior.getIndexInRealTerms(endArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
andrew@0 363
andrew@0 364 ofSetColor(0,0,100);
andrew@0 365 string relativeString = " offset "+ofToString(prior.offset, 1);//starttimes("+ofToString(startTimeMillis)+", "+ofToString(endTimeMillis);
andrew@0 366 relativeString += ": index "+ofToString(startArrayIndex)+" , "+ofToString(endArrayIndex)+" [";
andrew@0 367 // relativeString += ofToString(prior.getIndexInRealTerms(endArrayIndex), 3)+"] (sc-width:"+ofToString(screenWidthMillis, 1)+") ";
andrew@0 368 relativeString += " mapped to screen "+ofToString(startScreenPosition)+" , "+ofToString(endScreenPosition);
andrew@0 369 ofDrawBitmapString(relativeString, 100, 180);
andrew@0 370
andrew@1 371 ofSetColor(255, 255, 0);
andrew@0 372 likelihood.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 373
andrew@0 374 ofSetColor(0,0,200);
andrew@0 375 prior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 376
andrew@0 377 ofSetColor(200, 0, 0);
andrew@0 378 posterior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 379
andrew@1 380
andrew@0 381 // ofSetColor(0, 200, 255);
andrew@0 382 // acceleration.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 383
andrew@0 384
andrew@0 385 }
andrew@0 386
andrew@0 387 }