annotate src/BayesianArrayStructure.cpp @ 0:b299a65a3ad0

start project
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Tue, 16 Aug 2011 11:29:59 +0100
parents
children 1a32ce016bb9
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@0 249 relativeSpeedLikelihood.addConstant(0.02);
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@0 371 ofSetColor(0, 200, 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@0 380 // ofSetColor(0, 200, 255);
andrew@0 381 // acceleration.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 382
andrew@0 383
andrew@0 384 }
andrew@0 385
andrew@0 386 }