annotate bayesianArraySrc/BayesianArrayStructure.cpp @ 8:572564b7cb85

added calculation posterior into both onset and pitch processes
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Fri, 03 Feb 2012 13:28:59 +0000
parents 33dedfe32893
children cbadb9d05d29
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 //look at reset speed to one - what does this do? - get rid of?
andrew@0 11
andrew@0 12
andrew@0 13 #include "BayesianArrayStructure.h"
andrew@0 14
andrew@0 15 BayesianArrayStructure::BayesianArrayStructure(){
andrew@0 16 printf("Bayesian structure: DeFault constructor called");
andrew@0 17
andrew@4 18 usingIntegratedTempoEstimate = false;// use max index
andrew@7 19 updatingSpeedDistribution = false;
andrew@0 20
andrew@0 21 relativeSpeedLikelihoodStdDev = 5.0;
andrew@0 22
andrew@0 23 prior.createVector(1);
andrew@0 24 likelihood.createVector(1);
andrew@0 25 posterior.createVector(1);
andrew@0 26
andrew@0 27 speedPriorValue = 1.0;//default value for the speed prior
andrew@0 28 speedEstimate = speedPriorValue;
andrew@0 29
andrew@0 30 lastEventTime = 0;//ofGetElapsedTimeMillis();
andrew@0 31
andrew@0 32 tmpBestEstimate = 0;
andrew@5 33 crossUpdateTimeThreshold = 60;
andrew@3 34 priorWidth = 20;
andrew@0 35
andrew@0 36 }
andrew@0 37
andrew@0 38 BayesianArrayStructure::BayesianArrayStructure(int length){
andrew@0 39 printf("BAYESIAN STURCTURE CREATED LENGTH: %i\n", length);
andrew@0 40 //this constructor isnt called it seems
andrew@0 41 prior.createVector(length);
andrew@0 42 likelihood.createVector(length);
andrew@0 43 posterior.createVector(length);
andrew@0 44
andrew@0 45 lastEventTime = 0;
andrew@0 46
andrew@0 47
andrew@0 48 }
andrew@0 49
andrew@0 50
andrew@0 51
andrew@0 52 void BayesianArrayStructure::resetSize(int length){
andrew@0 53 printf("BAYESIAN STRUCTURE size is : %i\n", length);
andrew@0 54
andrew@0 55 prior.createVector(length);
andrew@0 56 likelihood.createVector(length);
andrew@0 57 posterior.createVector(length);
andrew@0 58
andrew@0 59 acceleration.createVector(length);
andrew@0 60
andrew@0 61 }
andrew@0 62
andrew@0 63 void BayesianArrayStructure::resetSpeedSize(int length){
andrew@0 64 printf("BAYESIAN reset SPEED size is : %i\n", length);
andrew@0 65
andrew@0 66 relativeSpeedPrior.createVector(length);
andrew@0 67 relativeSpeedLikelihood.createVector(length);
andrew@0 68 relativeSpeedPosterior.createVector(length);
andrew@0 69 tmpPosteriorForStorage.createVector(length);
andrew@0 70
andrew@0 71
andrew@0 72
andrew@0 73 }
andrew@0 74
andrew@0 75 void BayesianArrayStructure::setRelativeSpeedScalar(double f){
andrew@0 76 relativeSpeedPrior.scalar = f;
andrew@0 77 relativeSpeedPosterior.scalar = f;
andrew@0 78 relativeSpeedLikelihood.scalar = f;
andrew@0 79 }
andrew@0 80
andrew@0 81 void BayesianArrayStructure::resetSpeedToOne(){
andrew@0 82 relativeSpeedPrior.zero();
andrew@0 83 relativeSpeedPosterior.zero();
andrew@0 84 relativeSpeedLikelihood.zero();
andrew@0 85
andrew@0 86
andrew@0 87 relativeSpeedPosterior.addGaussianShape(100, 20, 0.8);
andrew@0 88 relativeSpeedPosterior.renormalise();
andrew@0 89 relativeSpeedPosterior.getMaximum();
andrew@0 90
andrew@0 91 setSpeedPrior(speedPriorValue);
andrew@0 92 speedEstimate = speedPriorValue;
andrew@0 93
andrew@0 94 prior.zero();
andrew@0 95 posterior.zero();
andrew@0 96
andrew@0 97 posterior.addToIndex(0, 1);
andrew@0 98 posterior.renormalise();
andrew@0 99
andrew@0 100 }
andrew@0 101
andrew@0 102 void BayesianArrayStructure::setSpeedPrior(double f){
andrew@0 103 speedPriorValue = f;
andrew@0 104 int index = relativeSpeedPosterior.getRealTermsAsIndex(speedPriorValue);
andrew@0 105 relativeSpeedPosterior.zero();
andrew@0 106 relativeSpeedPosterior.addGaussianShape(index, priorWidth, 0.8);
andrew@4 107 printf("speed adding to index for 1 = %f\n", relativeSpeedPosterior.getRealTermsAsIndex(1));
andrew@7 108 relativeSpeedPosterior.addToIndex(relativeSpeedPosterior.getRealTermsAsIndex(1), 0.1);
andrew@7 109 relativeSpeedPosterior.addGaussianShapeFromRealTime(1, 3, 0.5);
andrew@4 110
andrew@0 111 relativeSpeedPosterior.renormalise();
andrew@0 112 relativeSpeedPosterior.getMaximum();
andrew@0 113 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 114 printf("BAYES STRUCTU ' SPEED PRIOR %f . index %i\n", speedPriorValue, index);
andrew@0 115
andrew@0 116 }
andrew@0 117
andrew@0 118
andrew@0 119 void BayesianArrayStructure::setPositionDistributionScalar(double f){
andrew@0 120 if (f > 0){
andrew@0 121 prior.scalar = f;
andrew@0 122 posterior.scalar = f;
andrew@0 123 likelihood.scalar = f;
andrew@0 124 }
andrew@0 125 }
andrew@0 126
andrew@0 127 void BayesianArrayStructure::simpleExample(){
andrew@0 128 relativeSpeedPosterior.getMaximum();
andrew@0 129 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 130 }
andrew@0 131
andrew@0 132 void BayesianArrayStructure::copyPriorToPosterior(){
andrew@0 133
andrew@0 134 for (int i = 0;i < prior.arraySize;i++){
andrew@0 135 posterior.array[i] = prior.array[i];
andrew@0 136 }
andrew@0 137 }
andrew@0 138
andrew@0 139 void BayesianArrayStructure::setStartPlaying(){
andrew@0 140
andrew@0 141 lastEventTime = 0;
andrew@0 142 bestEstimate = 0;
andrew@0 143 lastBestEstimateUpdateTime = 0;
andrew@3 144
andrew@0 145 if (*realTimeMode)
andrew@0 146 lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
andrew@0 147 //cannot just be zero - offline bug
andrew@0 148 //printf("start playing - best estimate %f\n", lastBestEstimateUpdateTime);
andrew@0 149
andrew@0 150 resetArrays();
andrew@0 151 }
andrew@0 152
andrew@0 153 void BayesianArrayStructure::resetArrays(){
andrew@0 154 //called when we start playing
andrew@0 155
andrew@0 156 prior.zero();
andrew@0 157 likelihood.zero();
andrew@0 158 posterior.zero();
andrew@0 159
andrew@0 160 updateCounter = 0;
andrew@0 161
andrew@0 162 posterior.offset = -1000;
andrew@0 163 setNewDistributionOffsets(0);
andrew@0 164
andrew@0 165 int zeroIndex = posterior.getRealTermsAsIndex(0);
andrew@3 166 printf("ZERO INDEX %i\n", zeroIndex);
andrew@0 167
andrew@8 168 posterior.addGaussianShapeFromRealTime(0, 300, 1);//one way to add at x msec
andrew@7 169 // posterior.addGaussianShape(posterior.getRealTermsAsIndex(10), 50, 1);//alternative way
andrew@3 170
andrew@0 171 likelihood.addConstant(1);
andrew@0 172
andrew@0 173 updateCounter = 0;
andrew@0 174
andrew@0 175
andrew@0 176 printf("bayes reset arrays - best estimate %f\n", lastBestEstimateUpdateTime);
andrew@0 177
andrew@0 178 setSpeedPrior(speedPriorValue);
andrew@3 179 relativeSpeedPosterior.copyFromDynamicVector(relativeSpeedPrior);
andrew@3 180
andrew@0 181 }
andrew@0 182
andrew@0 183
andrew@0 184 void BayesianArrayStructure::zeroArrays(){
andrew@0 185 prior.zero();
andrew@0 186 likelihood.zero();
andrew@0 187 posterior.zero();
andrew@0 188
andrew@0 189 relativeSpeedPrior.zero();
andrew@0 190 relativeSpeedPosterior.zero();
andrew@0 191 relativeSpeedLikelihood.zero();
andrew@0 192
andrew@0 193 }
andrew@0 194
andrew@4 195 /*
andrew@0 196 void BayesianArrayStructure::updateTmpBestEstimate(const double& timeDifference){
andrew@0 197 //input is the time since the start of playing
andrew@0 198 // double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//lastBestEstimateUpdateTime;
andrew@0 199 double timeDiff = timeDifference;
andrew@0 200 if (*realTimeMode)
andrew@0 201 timeDiff = ofGetElapsedTimeMillis() - lastBestEstimateUpdateTime;
andrew@0 202
andrew@0 203 double tmp = relativeSpeedPosterior.getIntegratedEstimate();
andrew@0 204 tmpBestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
andrew@0 205 //
andrew@0 206 //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));
andrew@0 207 //lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
andrew@0 208 }
andrew@4 209 */
andrew@4 210
andrew@0 211 void BayesianArrayStructure::updateBestEstimate(const double& timeDifference){
andrew@0 212 // double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//
andrew@3 213 double tmp = bestEstimate;
andrew@4 214 printf("best est routine: posterior offset %f\n", posterior.offset);
andrew@0 215
andrew@0 216 double timeDiff = timeDifference;
andrew@0 217
andrew@0 218 //Using timedifferencfe here will make it go wrong. Is time since beginning of playing
andrew@0 219
andrew@0 220 if (*realTimeMode)
andrew@0 221 timeDiff = ofGetElapsedTimeMillis() - lastBestEstimateUpdateTime;
andrew@0 222
andrew@0 223 //lastbest is time we started playing
andrew@4 224 /*
andrew@0 225 if (usingIntegratedTempoEstimate)
andrew@0 226 speedEstimateIndex = relativeSpeedPosterior.getIntegratedEstimate();
andrew@0 227 else
andrew@4 228 speedEstimateIndex = relativeSpeedPosterior.getMAPestimate();
andrew@4 229 */
andrew@4 230 speedEstimateIndex = getSpeedEstimateIndex();
andrew@0 231
andrew@0 232 speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(speedEstimateIndex);
andrew@0 233 bestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*speedEstimate;
andrew@0 234
andrew@4 235 printf("best estimate update from %f to %f; time diff %f MAP %i = %f ms speed index %f est %f SpeedxTime %f\n", tmp, bestEstimate, timeDiff,
andrew@4 236 posterior.MAPestimate, posterior.getIndexInRealTerms(posterior.MAPestimate), speedEstimateIndex, speedEstimate, timeDiff*speedEstimate);
andrew@0 237 }
andrew@0 238
andrew@0 239 void BayesianArrayStructure::calculatePosterior(){
andrew@0 240 //posterior.doProduct(prior, likelihood);
andrew@4 241 assert(posterior.offset == prior.offset);
andrew@0 242
andrew@0 243 int i;
andrew@0 244 for (i = 0;i < posterior.length;i++){
andrew@0 245 posterior.array[i] = likelihood.array[i] * prior.array[i];
andrew@0 246 }
andrew@0 247
andrew@0 248 posterior.renormalise();
andrew@0 249
andrew@6 250 //tmp print stuff
andrew@6 251 printf("After CALC");
andrew@6 252 printPostOffset();
andrew@6 253
andrew@0 254 }
andrew@0 255
andrew@0 256
andrew@4 257 double BayesianArrayStructure::getSpeedEstimateIndex(){
andrew@4 258 if (usingIntegratedTempoEstimate)
andrew@4 259 return relativeSpeedPosterior.getIntegratedEstimate();
andrew@4 260 else
andrew@4 261 return relativeSpeedPosterior.getMAPestimate();
andrew@4 262 }
andrew@0 263
andrew@0 264
andrew@0 265 void BayesianArrayStructure::setNewDistributionOffsets(const double& newOffset){
andrew@4 266
andrew@4 267 printf("prior offset was %f now %f\n", prior.offset, newOffset);
andrew@4 268
andrew@0 269 prior.offset = newOffset;
andrew@0 270 likelihood.offset = newOffset;
andrew@4 271
andrew@0 272 //posterior.offset = newOffset;
andrew@0 273 }
andrew@0 274
andrew@0 275
andrew@6 276 void BayesianArrayStructure::updateBayesianDistributions(const double& newEventTime){
andrew@6 277
andrew@6 278 //NEED TO CHECK HERE THAT THEY HAVE THE SAME OFFSETS
andrew@6 279 prior.copyFromDynamicVector(posterior);//try the otehr way
andrew@6 280
andrew@6 281 //bayesianStruct.copyPriorToPosterior();
andrew@6 282 //need to get new MAP position and set the offset of the arrays
andrew@6 283 //currently bestEstimate is the approx for the new MAP position
andrew@6 284 // int tmpMap = bayesianStruct.posterior.getMAPestimate();
andrew@6 285
andrew@6 286 double timeDifference = newEventTime - lastEventTime;
andrew@6 287 // printf("updating distributions at time %f diff %f offset %f tmpmap est %i\n", newEventTime, timeDifference, bayesianStruct.posterior.offset, tmpMap);
andrew@6 288
andrew@6 289 //addnoise to the tempo distribution
andrew@6 290 //bayesianStruct.decaySpeedDistribution(timeDifference);
andrew@6 291
andrew@7 292 if (timeDifference > 50 && updatingSpeedDistribution){
andrew@6 293 addGaussianNoiseToSpeedPosterior(timeDifference * 10.0 / 100.);
andrew@6 294 }
andrew@6 295
andrew@6 296 printPostOffset();
andrew@6 297
andrew@6 298 updateBestEstimate(timeDifference);
andrew@6 299 lastBestEstimateUpdateTime = newEventTime;//getTimeNow(timePlayed);
andrew@6 300
andrew@8 301 //set TARGETS - commented tenmporarily
andrew@8 302 setNewDistributionOffsets(max(0., bestEstimate - (prior.scalar*prior.arraySize/2)));
andrew@6 303
andrew@6 304 crossUpdateArrays(posterior, relativeSpeedPosterior, timeDifference);
andrew@6 305
andrew@6 306 //i.e. using the same offset as prior
andrew@6 307 posterior.offset = prior.offset;//
andrew@6 308
andrew@6 309 // float tmpPrior = max(0., bestEstimate - (prior.scalar*prior.arraySize/2));// prior.offset = max(0., bestEstimate - (prior.scalar*prior.arraySize/2));
andrew@6 310 // printf("Using prior offset of %f not %f\n", tmpPrior, prior.offset);
andrew@6 311
andrew@6 312 lastEventTime = newEventTime;//lastEventTime = ofGetElapsedTimeMillis();
andrew@6 313
andrew@6 314 }
andrew@6 315
andrew@6 316
andrew@0 317 void BayesianArrayStructure::crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference){
andrew@8 318
andrew@0 319 //set the cutoff for offset of position first! XXX
andrew@0 320
andrew@0 321 double timeDifferenceInPositionVectorUnits = timeDifference / prior.scalar;
andrew@0 322
andrew@4 323 printf("CROSS UPDATE time diff %f ms is %f units; ", timeDifference, timeDifferenceInPositionVectorUnits);
andrew@0 324 prior.zero();//kill prior
andrew@4 325
andrew@4 326 // calculateNewPriorOffset(timeDifference);//dioesnt do anything
andrew@4 327
andrew@5 328 // printf("new prior offset %f and post offset %f\n", prior.offset, posterior.offset);
andrew@0 329
andrew@0 330 if (timeDifferenceInPositionVectorUnits > crossUpdateTimeThreshold)
andrew@0 331 complexCrossUpdate(timeDifferenceInPositionVectorUnits);
andrew@0 332 else
andrew@0 333 translateByMaximumSpeed(timeDifferenceInPositionVectorUnits);
andrew@0 334
andrew@0 335
andrew@0 336 updateCounter++;
andrew@8 337 prior.renormalise();//not strictly necessary??
andrew@0 338
andrew@0 339 }
andrew@0 340
andrew@0 341 void BayesianArrayStructure::complexCrossUpdate(const double& timeDifferenceInPositionVectorUnits){
andrew@4 342
andrew@5 343
andrew@5 344 printf("before cross c : posterior map is %i = %f ms time diff pos vec %f\n", posterior.getMAPestimate(), posterior.getIndexInRealTerms(prior.getMAPestimate()), timeDifferenceInPositionVectorUnits);
andrew@5 345
andrew@0 346 int distanceMoved, newPriorIndex;
andrew@0 347
andrew@0 348 double speedValue = relativeSpeedPosterior.offset;
andrew@0 349
andrew@0 350 for (int i = 0;i < relativeSpeedPosterior.arraySize;i++){
andrew@0 351
andrew@0 352 // double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
andrew@0 353
andrew@0 354 //so we have moved
andrew@0 355 distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
andrew@5 356 // printf("Speed value %f time %f gives distance %i\n", speedValue, timeDifferenceInPositionVectorUnits, distanceMoved);
andrew@5 357
andrew@0 358 if (relativeSpeedPosterior.array[i] != 0){
andrew@4 359
andrew@0 360 double speedContribution = relativeSpeedPosterior.array[i];
andrew@0 361
andrew@4 362 // printf("speed [%i](val[%f]) gives %f moved %i in %f units \n", i, relativeSpeedPosterior.array[i], speedValue, distanceMoved, timeDifferenceInPositionVectorUnits);
andrew@0 363
andrew@4 364 //1/2/12 deleted line
andrew@4 365 newPriorIndex = posterior.offset - prior.offset + distanceMoved;//i.e. where post[0] goes to in terms of prior at this speed
andrew@5 366 int postIndex = 0;//index of posterior that will contribute
andrew@5 367
andrew@4 368 while (postIndex < posterior.arraySize && newPriorIndex < prior.arraySize){
andrew@4 369
andrew@4 370 //did use a for loop
andrew@4 371 // for (postIndex = 0;postIndex < posterior.arraySize;postIndex++){
andrew@0 372 //old posterior contributing to new prior
andrew@4 373
andrew@4 374 //would use this method
andrew@4 375 //newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
andrew@0 376
andrew@4 377 if (newPriorIndex >= 0){
andrew@0 378 prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
andrew@4 379 // printf("speed index %i new prior index %i post val %f speed contrib %f dist %i\n", i, newPriorIndex, posterior.array[postIndex], speedContribution, distanceMoved);
andrew@0 380 }
andrew@4 381 //but we actually do this for simplicity
andrew@4 382 newPriorIndex++;
andrew@4 383 postIndex++;
andrew@4 384 }//end for. now while
andrew@0 385
andrew@0 386
andrew@0 387 }//if not zero
andrew@5 388
andrew@5 389 speedValue += relativeSpeedPosterior.scalar;//optimised line
andrew@0 390 //as we wanted:
andrew@0 391 // double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
andrew@5 392
andrew@0 393 }//end speed
andrew@5 394
andrew@5 395
andrew@5 396 printf("after cross c : prior map is %i = %f ms\n", prior.getMAPestimate(), prior.getIndexInRealTerms(prior.getMAPestimate()));
andrew@0 397 }
andrew@0 398
andrew@0 399
andrew@0 400
andrew@0 401 void BayesianArrayStructure::translateByMaximumSpeed(const double& timeDifferenceInPositionVectorUnits){
andrew@0 402
andrew@8 403
andrew@0 404 int distanceMoved, newPriorIndex;
andrew@8 405 double speedIndex = getSpeedEstimateIndex();
andrew@8 406 double speedValue = relativeSpeedPosterior.getIndexInRealTerms(speedIndex);
andrew@0 407
andrew@8 408 // double speedValue = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
andrew@8 409
andrew@0 410 //so for scalar 0.01, 50 -> speed value of 0.5
andrew@8 411 double speedContribution = relativeSpeedPosterior.array[(int)round(speedIndex)];
andrew@0 412 //so we have moved
andrew@0 413 distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
andrew@8 414
andrew@8 415 // printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits);
andrew@0 416
andrew@0 417 for (int postIndex = 0;postIndex < posterior.arraySize;postIndex++){
andrew@0 418 //old posterior contributing to new prior
andrew@0 419 newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
andrew@0 420 if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
andrew@0 421 prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
andrew@0 422 }
andrew@0 423
andrew@0 424 }
andrew@0 425
andrew@0 426 }
andrew@0 427
andrew@0 428 void BayesianArrayStructure::addGaussianNoiseToSpeedPosterior(const double& std_dev){
andrew@0 429 tmpPosteriorForStorage.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 430
andrew@0 431 for (int i = 0;i < relativeSpeedPosterior.length;i++){
andrew@0 432 tmpPosteriorForStorage.addGaussianShape(i, std_dev, relativeSpeedPosterior.array[i]);
andrew@0 433 }
andrew@0 434
andrew@0 435 tmpPosteriorForStorage.renormalise();
andrew@0 436
andrew@0 437 relativeSpeedPosterior.copyFromDynamicVector(tmpPosteriorForStorage);
andrew@0 438 }
andrew@0 439
andrew@0 440
andrew@0 441 void BayesianArrayStructure::addTriangularNoiseToSpeedPosterior(const double& std_dev){
andrew@0 442 tmpPosteriorForStorage.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 443
andrew@0 444 for (int i = 0;i < relativeSpeedPosterior.length;i++){
andrew@0 445 //adding a linear amount depending on distance
andrew@0 446 tmpPosteriorForStorage.addTriangularShape(i, std_dev*2.0, relativeSpeedPosterior.array[i]);
andrew@0 447 }
andrew@0 448
andrew@0 449 tmpPosteriorForStorage.renormalise();
andrew@0 450
andrew@0 451 relativeSpeedPosterior.copyFromDynamicVector(tmpPosteriorForStorage);
andrew@0 452 }
andrew@0 453
andrew@0 454 void BayesianArrayStructure::calculateNewPriorOffset(const double& timeDifference){
andrew@0 455
andrew@4 456 // double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
andrew@4 457
andrew@4 458 double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(getSpeedEstimateIndex());//either integrated or MAP
andrew@0 459 // printf("Maxspeed is %f\n", maxSpeed);
andrew@0 460
andrew@0 461 double priorMax = posterior.getMaximum();
andrew@0 462 double distanceTravelled = maxSpeed * (timeDifference / prior.scalar);
andrew@0 463 double newMaxLocation = posterior.MAPestimate + distanceTravelled;
andrew@0 464 // printf("MAP: %i, tim df %f, distance %f, new location %f\n", posterior.MAPestimate, timeDifference, distanceTravelled, newMaxLocation);
andrew@0 465
andrew@0 466 }
andrew@0 467
andrew@0 468
andrew@0 469 void BayesianArrayStructure::decaySpeedDistribution(double timeDifference){
andrew@0 470
andrew@0 471 // commented for the moment
andrew@0 472 double relativeAmount = max(1.0, timeDifference/1000.);
andrew@0 473 // printf("decay %f around %i \n", timeDifference, relativeSpeedPosterior.MAPestimate);
andrew@0 474 relativeAmount *= speedDecayAmount;
andrew@0 475 relativeSpeedPosterior.renormalise();
andrew@0 476 relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, relativeAmount);
andrew@0 477
andrew@0 478 relativeSpeedPosterior.renormalise();
andrew@0 479 double newMax = relativeSpeedPosterior.getMaximum();
andrew@0 480
andrew@0 481 //old code
andrew@0 482 // relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, 10);
andrew@0 483 //relativeSpeedPosterior.addConstant(1);
andrew@0 484
andrew@0 485 /*
andrew@0 486 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 487 relativeSpeedLikelihood.zero();
andrew@0 488 relativeSpeedLikelihood.addConstant(0.2);
andrew@0 489 relativeSpeedLikelihood.addGaussianShape(relativeSpeedPosterior.maximumValue, speedDecayWidth, relativeAmount);
andrew@0 490 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
andrew@0 491 relativeSpeedPosterior.renormalise();
andrew@0 492 */
andrew@0 493
andrew@0 494
andrew@0 495
andrew@0 496 }
andrew@0 497
andrew@0 498 void BayesianArrayStructure::setLikelihoodToConstant(){
andrew@0 499 //set new likelihood
andrew@0 500 relativeSpeedLikelihood.zero();
andrew@0 501 relativeSpeedLikelihood.addConstant(speedLikelihoodNoise);
andrew@0 502 }
andrew@0 503
andrew@0 504
andrew@0 505 void BayesianArrayStructure::updateTempoLikelihood(const double& speedRatio, const double& matchFactor){
andrew@0 506
andrew@0 507 //speedratio is speed of played relative to the recording
andrew@0 508
andrew@0 509 double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
andrew@0 510 // printf("index of likelihood would be %f for ratio %f\n", index, speedRatio);
andrew@0 511 if (index >= 0 && index < relativeSpeedPrior.length){
andrew@0 512 relativeSpeedLikelihood.addGaussianShape(index , relativeSpeedLikelihoodStdDev, matchFactor);
andrew@0 513 }
andrew@0 514 }
andrew@0 515
andrew@0 516
andrew@0 517
andrew@0 518 void BayesianArrayStructure::updateTempoDistribution(){
andrew@0 519
andrew@0 520 //copy posterior to prior
andrew@0 521 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 522
andrew@0 523 //update
andrew@0 524 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
andrew@0 525
andrew@0 526 //normalise
andrew@0 527 relativeSpeedPosterior.renormalise();
andrew@0 528
andrew@0 529 relativeSpeedPosterior.getMaximum();
andrew@0 530
andrew@0 531 //relativeSpeedPosterior.updateIntegratedEstimate(); - could be swayed when off to side
andrew@0 532 //so now limited to where there is room sround the MAP estimate
andrew@0 533 relativeSpeedPosterior.updateLimitedIntegratedEstimate();
andrew@0 534
andrew@0 535 speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
andrew@0 536 }
andrew@0 537
andrew@0 538
andrew@0 539 void BayesianArrayStructure::calculateTempoUpdate(){
andrew@0 540 //copy posterior to prior
andrew@0 541 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 542
andrew@0 543 //update
andrew@0 544 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
andrew@0 545
andrew@0 546 //normalise
andrew@0 547 relativeSpeedPosterior.renormalise();
andrew@0 548
andrew@0 549 relativeSpeedPosterior.getMaximum();
andrew@0 550
andrew@0 551 }
andrew@0 552
andrew@0 553
andrew@0 554 void BayesianArrayStructure::drawArrays(){
andrew@0 555
andrew@0 556 //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
andrew@0 557 //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
andrew@0 558
andrew@0 559 int displaySize = prior.arraySize;
andrew@0 560 ofSetColor(0,0,255);
andrew@0 561 prior.drawVector(0, displaySize);
andrew@0 562 ofSetColor(0,255,0);
andrew@0 563 likelihood.drawVector(0, displaySize);
andrew@0 564 ofSetColor(255,0,255);
andrew@0 565 posterior.drawVector(0, displaySize);
andrew@0 566
andrew@0 567
andrew@0 568
andrew@0 569 }
andrew@0 570
andrew@0 571
andrew@0 572 void BayesianArrayStructure::drawTempoArrays(){
andrew@0 573 ofSetColor(0,0,255);
andrew@0 574 // relativeSpeedPrior.drawVector(0, relativeSpeedPrior.arraySize);
andrew@0 575
andrew@0 576 ofSetColor(0,150,255);
andrew@0 577 relativeSpeedLikelihood.drawVector(0, relativeSpeedLikelihood.arraySize);
andrew@0 578
andrew@0 579 // relativeSpeedLikelihood.drawConstrainedVector(0, 199, 0, 1000);// relativeSpeedLikelihood.arraySize);
andrew@0 580 ofSetColor(255,0,0);
andrew@0 581 relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize);
andrew@0 582
andrew@0 583 // ofSetColor(0,0,255);
andrew@0 584 // tmpPosteriorForStorage.drawVector(0, tmpPosteriorForStorage.arraySize);
andrew@0 585
andrew@0 586 ofSetColor(255,255, 255);
andrew@0 587 ofLine(screenWidth/2, 0, screenWidth/2, ofGetHeight());//middle of screen
andrew@0 588
andrew@0 589 ofSetColor(25, 0, 250);
andrew@0 590 double fractionOfScreen = ((double)relativeSpeedPosterior.integratedEstimate / relativeSpeedPosterior.length);
andrew@0 591 ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
andrew@0 592
andrew@0 593 ofSetColor(255, 0, 20);
andrew@0 594 fractionOfScreen = ((double)relativeSpeedPosterior.MAPestimate / relativeSpeedPosterior.length);
andrew@0 595 ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
andrew@0 596
andrew@0 597
andrew@0 598 }
andrew@0 599
andrew@0 600
andrew@0 601 void BayesianArrayStructure::drawArraysRelativeToTimeframe(const double& startTimeMillis, const double& endTimeMillis){
andrew@0 602
andrew@0 603 screenWidth = ofGetWidth();
andrew@0 604
andrew@0 605 int startArrayIndex = 0;
andrew@0 606
andrew@0 607 if (prior.getIndexInRealTerms(prior.arraySize-1) > startTimeMillis){
andrew@0 608 //i.e. the array is on the page
andrew@0 609
andrew@0 610 while (prior.getIndexInRealTerms(startArrayIndex) < startTimeMillis){
andrew@0 611 startArrayIndex++;
andrew@0 612 }
andrew@0 613 int endArrayIndex = prior.arraySize-1;
andrew@0 614 //could find constraints here
andrew@0 615 if (prior.getIndexInRealTerms(prior.arraySize-1) > endTimeMillis)
andrew@0 616 endArrayIndex = (floor)((endTimeMillis - prior.offset)/prior.scalar);
andrew@0 617
andrew@0 618 //so we need to figure where start and end array are on screen
andrew@0 619 int startScreenPosition, endScreenPosition;
andrew@0 620 double screenWidthMillis = endTimeMillis - startTimeMillis;
andrew@0 621
andrew@0 622 startScreenPosition = (prior.getIndexInRealTerms(startArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
andrew@0 623 endScreenPosition = (double)(prior.getIndexInRealTerms(endArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
andrew@0 624
andrew@0 625 ofSetColor(0,0,100);
andrew@0 626 string relativeString = " offset "+ofToString(prior.offset, 1);//starttimes("+ofToString(startTimeMillis)+", "+ofToString(endTimeMillis);
andrew@0 627 relativeString += ": index "+ofToString(startArrayIndex)+" , "+ofToString(endArrayIndex)+" [";
andrew@0 628 // relativeString += ofToString(prior.getIndexInRealTerms(endArrayIndex), 3)+"] (sc-width:"+ofToString(screenWidthMillis, 1)+") ";
andrew@0 629 relativeString += " mapped to screen "+ofToString(startScreenPosition)+" , "+ofToString(endScreenPosition);
andrew@0 630 // ofDrawBitmapString(relativeString, 100, 180);
andrew@0 631
andrew@0 632
andrew@0 633
andrew@0 634 ofSetColor(100,100,100);//255, 255, 0);
andrew@0 635 likelihood.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 636
andrew@0 637 // ofSetColor(0,0,200);
andrew@0 638 ofSetColor(170,170,170);//00,200);
andrew@0 639 prior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 640
andrew@0 641 ofSetColor(0,0,150);
andrew@0 642 // ofSetColor(200, 0, 0);
andrew@0 643 posterior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 644
andrew@0 645
andrew@0 646 // ofSetColor(0, 200, 255);
andrew@0 647 // acceleration.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 648
andrew@0 649
andrew@0 650 }
andrew@0 651
andrew@0 652 }
andrew@0 653
andrew@0 654
andrew@6 655 void BayesianArrayStructure::printPostOffset(){
andrew@6 656 double tmp = posterior.getMAPestimate();
andrew@6 657 printf(" MAP index %i post offset %f == %f ms\n", posterior.MAPestimate, posterior.offset, posterior.getIndexInRealTerms(posterior.MAPestimate));
andrew@6 658 }
andrew@6 659
andrew@0 660 /*
andrew@0 661
andrew@0 662 void BayesianArrayStructure::updateTempoDistribution(const double& speedRatio, const double& matchFactor){
andrew@0 663 //speedratio is speed of played relative to the recording
andrew@0 664
andrew@0 665 double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
andrew@0 666 // printf("\nindex of likelihood would be %f\n", index);
andrew@0 667 if (index >= 0 && index < relativeSpeedPrior.length){
andrew@0 668 //then we can do update
andrew@0 669
andrew@0 670 //set new likelihood
andrew@0 671 relativeSpeedLikelihood.zero();
andrew@0 672 relativeSpeedLikelihood.addConstant(speedLikelihoodNoise);
andrew@0 673
andrew@0 674 relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5*matchFactor);
andrew@0 675
andrew@0 676
andrew@0 677 //copy posterior to prior
andrew@0 678 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 679
andrew@0 680 //update
andrew@0 681 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
andrew@0 682
andrew@0 683 //normalise
andrew@0 684 relativeSpeedPosterior.renormalise();
andrew@0 685
andrew@0 686 relativeSpeedPosterior.getMaximum();
andrew@0 687 }//end if within range
andrew@0 688
andrew@0 689
andrew@0 690 }
andrew@0 691
andrew@0 692 */