annotate bayesianArraySrc/BayesianArrayStructure.cpp @ 11:9a2b008c4706

Priors for each channel and scrolling projection for new prior is added
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Sun, 05 Feb 2012 00:00:58 +0000
parents cbadb9d05d29
children 780def3a1f36
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@11 110
andrew@11 111
andrew@11 112 //tmp debug test
andrew@11 113 //relativeSpeedPosterior.addToIndex(relativeSpeedPosterior.getRealTermsAsIndex(1.8), 0.15);
andrew@4 114
andrew@0 115 relativeSpeedPosterior.renormalise();
andrew@0 116 relativeSpeedPosterior.getMaximum();
andrew@11 117
andrew@11 118
andrew@0 119 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@11 120
andrew@11 121
andrew@11 122
andrew@0 123 printf("BAYES STRUCTU ' SPEED PRIOR %f . index %i\n", speedPriorValue, index);
andrew@0 124
andrew@0 125 }
andrew@0 126
andrew@0 127
andrew@0 128 void BayesianArrayStructure::setPositionDistributionScalar(double f){
andrew@0 129 if (f > 0){
andrew@0 130 prior.scalar = f;
andrew@0 131 posterior.scalar = f;
andrew@0 132 likelihood.scalar = f;
andrew@0 133 }
andrew@0 134 }
andrew@0 135
andrew@0 136 void BayesianArrayStructure::simpleExample(){
andrew@0 137 relativeSpeedPosterior.getMaximum();
andrew@0 138 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 139 }
andrew@0 140
andrew@0 141 void BayesianArrayStructure::copyPriorToPosterior(){
andrew@0 142
andrew@0 143 for (int i = 0;i < prior.arraySize;i++){
andrew@0 144 posterior.array[i] = prior.array[i];
andrew@0 145 }
andrew@0 146 }
andrew@0 147
andrew@0 148 void BayesianArrayStructure::setStartPlaying(){
andrew@0 149
andrew@0 150 lastEventTime = 0;
andrew@0 151 bestEstimate = 0;
andrew@0 152 lastBestEstimateUpdateTime = 0;
andrew@3 153
andrew@0 154 if (*realTimeMode)
andrew@0 155 lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
andrew@0 156 //cannot just be zero - offline bug
andrew@0 157 //printf("start playing - best estimate %f\n", lastBestEstimateUpdateTime);
andrew@0 158
andrew@0 159 resetArrays();
andrew@0 160 }
andrew@0 161
andrew@0 162 void BayesianArrayStructure::resetArrays(){
andrew@0 163 //called when we start playing
andrew@0 164
andrew@0 165 prior.zero();
andrew@0 166 likelihood.zero();
andrew@0 167 posterior.zero();
andrew@0 168
andrew@0 169 updateCounter = 0;
andrew@0 170
andrew@0 171 posterior.offset = -1000;
andrew@0 172 setNewDistributionOffsets(0);
andrew@0 173
andrew@0 174 int zeroIndex = posterior.getRealTermsAsIndex(0);
andrew@3 175 printf("ZERO INDEX %i\n", zeroIndex);
andrew@0 176
andrew@8 177 posterior.addGaussianShapeFromRealTime(0, 300, 1);//one way to add at x msec
andrew@7 178 // posterior.addGaussianShape(posterior.getRealTermsAsIndex(10), 50, 1);//alternative way
andrew@3 179
andrew@0 180 likelihood.addConstant(1);
andrew@0 181
andrew@0 182 updateCounter = 0;
andrew@0 183
andrew@0 184
andrew@0 185 printf("bayes reset arrays - best estimate %f\n", lastBestEstimateUpdateTime);
andrew@0 186
andrew@0 187 setSpeedPrior(speedPriorValue);
andrew@3 188 relativeSpeedPosterior.copyFromDynamicVector(relativeSpeedPrior);
andrew@3 189
andrew@0 190 }
andrew@0 191
andrew@0 192
andrew@0 193 void BayesianArrayStructure::zeroArrays(){
andrew@0 194 prior.zero();
andrew@0 195 likelihood.zero();
andrew@0 196 posterior.zero();
andrew@0 197
andrew@0 198 relativeSpeedPrior.zero();
andrew@0 199 relativeSpeedPosterior.zero();
andrew@0 200 relativeSpeedLikelihood.zero();
andrew@0 201
andrew@0 202 }
andrew@0 203
andrew@4 204 /*
andrew@0 205 void BayesianArrayStructure::updateTmpBestEstimate(const double& timeDifference){
andrew@0 206 //input is the time since the start of playing
andrew@0 207 // double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//lastBestEstimateUpdateTime;
andrew@0 208 double timeDiff = timeDifference;
andrew@0 209 if (*realTimeMode)
andrew@0 210 timeDiff = ofGetElapsedTimeMillis() - lastBestEstimateUpdateTime;
andrew@0 211
andrew@0 212 double tmp = relativeSpeedPosterior.getIntegratedEstimate();
andrew@0 213 tmpBestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
andrew@0 214 //
andrew@0 215 //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 216 //lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
andrew@0 217 }
andrew@4 218 */
andrew@4 219
andrew@0 220 void BayesianArrayStructure::updateBestEstimate(const double& timeDifference){
andrew@0 221 // double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//
andrew@3 222 double tmp = bestEstimate;
andrew@10 223 // printf("best est routine: posterior offset %f\n", posterior.offset);
andrew@0 224
andrew@0 225 double timeDiff = timeDifference;
andrew@0 226
andrew@0 227 //Using timedifferencfe here will make it go wrong. Is time since beginning of playing
andrew@0 228
andrew@0 229 if (*realTimeMode)
andrew@0 230 timeDiff = ofGetElapsedTimeMillis() - lastBestEstimateUpdateTime;
andrew@0 231
andrew@0 232 //lastbest is time we started playing
andrew@4 233 /*
andrew@0 234 if (usingIntegratedTempoEstimate)
andrew@0 235 speedEstimateIndex = relativeSpeedPosterior.getIntegratedEstimate();
andrew@0 236 else
andrew@4 237 speedEstimateIndex = relativeSpeedPosterior.getMAPestimate();
andrew@4 238 */
andrew@4 239 speedEstimateIndex = getSpeedEstimateIndex();
andrew@0 240
andrew@0 241 speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(speedEstimateIndex);
andrew@0 242 bestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*speedEstimate;
andrew@0 243
andrew@10 244 // 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@10 245 // posterior.MAPestimate, posterior.getIndexInRealTerms(posterior.MAPestimate), speedEstimateIndex, speedEstimate, timeDiff*speedEstimate);
andrew@10 246 printf("BEST ESTIMATE %f\n", bestEstimate);
andrew@0 247 }
andrew@0 248
andrew@10 249
andrew@0 250 void BayesianArrayStructure::calculatePosterior(){
andrew@0 251 //posterior.doProduct(prior, likelihood);
andrew@4 252 assert(posterior.offset == prior.offset);
andrew@0 253
andrew@0 254 int i;
andrew@0 255 for (i = 0;i < posterior.length;i++){
andrew@0 256 posterior.array[i] = likelihood.array[i] * prior.array[i];
andrew@0 257 }
andrew@0 258
andrew@0 259 posterior.renormalise();
andrew@0 260
andrew@6 261 //tmp print stuff
andrew@6 262 printf("After CALC");
andrew@6 263 printPostOffset();
andrew@6 264
andrew@0 265 }
andrew@0 266
andrew@0 267
andrew@4 268 double BayesianArrayStructure::getSpeedEstimateIndex(){
andrew@4 269 if (usingIntegratedTempoEstimate)
andrew@4 270 return relativeSpeedPosterior.getIntegratedEstimate();
andrew@4 271 else
andrew@4 272 return relativeSpeedPosterior.getMAPestimate();
andrew@4 273 }
andrew@0 274
andrew@0 275
andrew@0 276 void BayesianArrayStructure::setNewDistributionOffsets(const double& newOffset){
andrew@4 277
andrew@4 278 printf("prior offset was %f now %f\n", prior.offset, newOffset);
andrew@4 279
andrew@0 280 prior.offset = newOffset;
andrew@0 281 likelihood.offset = newOffset;
andrew@4 282
andrew@0 283 //posterior.offset = newOffset;
andrew@0 284 }
andrew@0 285
andrew@0 286
andrew@6 287 void BayesianArrayStructure::updateBayesianDistributions(const double& newEventTime){
andrew@6 288
andrew@6 289 //NEED TO CHECK HERE THAT THEY HAVE THE SAME OFFSETS
andrew@6 290 prior.copyFromDynamicVector(posterior);//try the otehr way
andrew@6 291
andrew@6 292 //bayesianStruct.copyPriorToPosterior();
andrew@6 293 //need to get new MAP position and set the offset of the arrays
andrew@6 294 //currently bestEstimate is the approx for the new MAP position
andrew@6 295 // int tmpMap = bayesianStruct.posterior.getMAPestimate();
andrew@6 296
andrew@6 297 double timeDifference = newEventTime - lastEventTime;
andrew@10 298 printf("updating distributions at time %f diff %f offset %f\n", newEventTime, timeDifference, posterior.offset);
andrew@6 299
andrew@6 300 //addnoise to the tempo distribution
andrew@6 301 //bayesianStruct.decaySpeedDistribution(timeDifference);
andrew@6 302
andrew@7 303 if (timeDifference > 50 && updatingSpeedDistribution){
andrew@6 304 addGaussianNoiseToSpeedPosterior(timeDifference * 10.0 / 100.);
andrew@6 305 }
andrew@6 306
andrew@6 307 printPostOffset();
andrew@6 308
andrew@6 309 updateBestEstimate(timeDifference);
andrew@6 310 lastBestEstimateUpdateTime = newEventTime;//getTimeNow(timePlayed);
andrew@6 311
andrew@8 312 //set TARGETS - commented tenmporarily
andrew@8 313 setNewDistributionOffsets(max(0., bestEstimate - (prior.scalar*prior.arraySize/2)));
andrew@6 314
andrew@6 315 crossUpdateArrays(posterior, relativeSpeedPosterior, timeDifference);
andrew@6 316
andrew@6 317 //i.e. using the same offset as prior
andrew@6 318 posterior.offset = prior.offset;//
andrew@6 319
andrew@6 320 // float tmpPrior = max(0., bestEstimate - (prior.scalar*prior.arraySize/2));// prior.offset = max(0., bestEstimate - (prior.scalar*prior.arraySize/2));
andrew@6 321 // printf("Using prior offset of %f not %f\n", tmpPrior, prior.offset);
andrew@6 322
andrew@6 323 lastEventTime = newEventTime;//lastEventTime = ofGetElapsedTimeMillis();
andrew@6 324
andrew@6 325 }
andrew@6 326
andrew@6 327
andrew@10 328
andrew@10 329
andrew@0 330 void BayesianArrayStructure::crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference){
andrew@8 331
andrew@0 332 //set the cutoff for offset of position first! XXX
andrew@0 333
andrew@0 334 double timeDifferenceInPositionVectorUnits = timeDifference / prior.scalar;
andrew@0 335
andrew@4 336 printf("CROSS UPDATE time diff %f ms is %f units; ", timeDifference, timeDifferenceInPositionVectorUnits);
andrew@0 337 prior.zero();//kill prior
andrew@4 338
andrew@4 339 // calculateNewPriorOffset(timeDifference);//dioesnt do anything
andrew@4 340
andrew@5 341 // printf("new prior offset %f and post offset %f\n", prior.offset, posterior.offset);
andrew@0 342
andrew@0 343 if (timeDifferenceInPositionVectorUnits > crossUpdateTimeThreshold)
andrew@0 344 complexCrossUpdate(timeDifferenceInPositionVectorUnits);
andrew@0 345 else
andrew@0 346 translateByMaximumSpeed(timeDifferenceInPositionVectorUnits);
andrew@0 347
andrew@0 348
andrew@0 349 updateCounter++;
andrew@8 350 prior.renormalise();//not strictly necessary??
andrew@0 351
andrew@0 352 }
andrew@0 353
andrew@0 354 void BayesianArrayStructure::complexCrossUpdate(const double& timeDifferenceInPositionVectorUnits){
andrew@4 355
andrew@5 356
andrew@5 357 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 358
andrew@0 359 int distanceMoved, newPriorIndex;
andrew@0 360
andrew@0 361 double speedValue = relativeSpeedPosterior.offset;
andrew@0 362
andrew@0 363 for (int i = 0;i < relativeSpeedPosterior.arraySize;i++){
andrew@0 364
andrew@0 365 // double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
andrew@0 366
andrew@0 367 //so we have moved
andrew@0 368 distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
andrew@5 369 // printf("Speed value %f time %f gives distance %i\n", speedValue, timeDifferenceInPositionVectorUnits, distanceMoved);
andrew@5 370
andrew@0 371 if (relativeSpeedPosterior.array[i] != 0){
andrew@4 372
andrew@0 373 double speedContribution = relativeSpeedPosterior.array[i];
andrew@0 374
andrew@4 375 // printf("speed [%i](val[%f]) gives %f moved %i in %f units \n", i, relativeSpeedPosterior.array[i], speedValue, distanceMoved, timeDifferenceInPositionVectorUnits);
andrew@0 376
andrew@4 377 //1/2/12 deleted line
andrew@4 378 newPriorIndex = posterior.offset - prior.offset + distanceMoved;//i.e. where post[0] goes to in terms of prior at this speed
andrew@5 379 int postIndex = 0;//index of posterior that will contribute
andrew@5 380
andrew@4 381 while (postIndex < posterior.arraySize && newPriorIndex < prior.arraySize){
andrew@4 382
andrew@4 383 //did use a for loop
andrew@4 384 // for (postIndex = 0;postIndex < posterior.arraySize;postIndex++){
andrew@0 385 //old posterior contributing to new prior
andrew@4 386
andrew@4 387 //would use this method
andrew@4 388 //newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
andrew@0 389
andrew@4 390 if (newPriorIndex >= 0){
andrew@0 391 prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
andrew@4 392 // 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 393 }
andrew@4 394 //but we actually do this for simplicity
andrew@4 395 newPriorIndex++;
andrew@4 396 postIndex++;
andrew@4 397 }//end for. now while
andrew@0 398
andrew@0 399
andrew@0 400 }//if not zero
andrew@5 401
andrew@5 402 speedValue += relativeSpeedPosterior.scalar;//optimised line
andrew@0 403 //as we wanted:
andrew@0 404 // double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
andrew@5 405
andrew@0 406 }//end speed
andrew@5 407
andrew@5 408
andrew@5 409 printf("after cross c : prior map is %i = %f ms\n", prior.getMAPestimate(), prior.getIndexInRealTerms(prior.getMAPestimate()));
andrew@0 410 }
andrew@0 411
andrew@0 412
andrew@0 413
andrew@0 414 void BayesianArrayStructure::translateByMaximumSpeed(const double& timeDifferenceInPositionVectorUnits){
andrew@0 415
andrew@8 416
andrew@0 417 int distanceMoved, newPriorIndex;
andrew@8 418 double speedIndex = getSpeedEstimateIndex();
andrew@8 419 double speedValue = relativeSpeedPosterior.getIndexInRealTerms(speedIndex);
andrew@0 420
andrew@8 421 // double speedValue = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
andrew@8 422
andrew@0 423 //so for scalar 0.01, 50 -> speed value of 0.5
andrew@8 424 double speedContribution = relativeSpeedPosterior.array[(int)round(speedIndex)];
andrew@0 425 //so we have moved
andrew@0 426 distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
andrew@8 427
andrew@8 428 // printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits);
andrew@0 429
andrew@0 430 for (int postIndex = 0;postIndex < posterior.arraySize;postIndex++){
andrew@0 431 //old posterior contributing to new prior
andrew@0 432 newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
andrew@0 433 if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
andrew@0 434 prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
andrew@0 435 }
andrew@0 436
andrew@0 437 }
andrew@0 438
andrew@0 439 }
andrew@0 440
andrew@0 441 void BayesianArrayStructure::addGaussianNoiseToSpeedPosterior(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 tmpPosteriorForStorage.addGaussianShape(i, std_dev, relativeSpeedPosterior.array[i]);
andrew@0 446 }
andrew@0 447
andrew@0 448 tmpPosteriorForStorage.renormalise();
andrew@0 449
andrew@0 450 relativeSpeedPosterior.copyFromDynamicVector(tmpPosteriorForStorage);
andrew@0 451 }
andrew@0 452
andrew@0 453
andrew@0 454 void BayesianArrayStructure::addTriangularNoiseToSpeedPosterior(const double& std_dev){
andrew@0 455 tmpPosteriorForStorage.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 456
andrew@0 457 for (int i = 0;i < relativeSpeedPosterior.length;i++){
andrew@0 458 //adding a linear amount depending on distance
andrew@0 459 tmpPosteriorForStorage.addTriangularShape(i, std_dev*2.0, relativeSpeedPosterior.array[i]);
andrew@0 460 }
andrew@0 461
andrew@0 462 tmpPosteriorForStorage.renormalise();
andrew@0 463
andrew@0 464 relativeSpeedPosterior.copyFromDynamicVector(tmpPosteriorForStorage);
andrew@0 465 }
andrew@0 466
andrew@0 467 void BayesianArrayStructure::calculateNewPriorOffset(const double& timeDifference){
andrew@0 468
andrew@4 469 // double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
andrew@4 470
andrew@4 471 double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(getSpeedEstimateIndex());//either integrated or MAP
andrew@0 472 // printf("Maxspeed is %f\n", maxSpeed);
andrew@0 473
andrew@0 474 double priorMax = posterior.getMaximum();
andrew@0 475 double distanceTravelled = maxSpeed * (timeDifference / prior.scalar);
andrew@0 476 double newMaxLocation = posterior.MAPestimate + distanceTravelled;
andrew@0 477 // printf("MAP: %i, tim df %f, distance %f, new location %f\n", posterior.MAPestimate, timeDifference, distanceTravelled, newMaxLocation);
andrew@0 478
andrew@0 479 }
andrew@0 480
andrew@0 481
andrew@0 482 void BayesianArrayStructure::decaySpeedDistribution(double timeDifference){
andrew@0 483
andrew@0 484 // commented for the moment
andrew@0 485 double relativeAmount = max(1.0, timeDifference/1000.);
andrew@0 486 // printf("decay %f around %i \n", timeDifference, relativeSpeedPosterior.MAPestimate);
andrew@0 487 relativeAmount *= speedDecayAmount;
andrew@0 488 relativeSpeedPosterior.renormalise();
andrew@0 489 relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, relativeAmount);
andrew@0 490
andrew@0 491 relativeSpeedPosterior.renormalise();
andrew@0 492 double newMax = relativeSpeedPosterior.getMaximum();
andrew@0 493
andrew@0 494 //old code
andrew@0 495 // relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, 10);
andrew@0 496 //relativeSpeedPosterior.addConstant(1);
andrew@0 497
andrew@0 498 /*
andrew@0 499 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 500 relativeSpeedLikelihood.zero();
andrew@0 501 relativeSpeedLikelihood.addConstant(0.2);
andrew@0 502 relativeSpeedLikelihood.addGaussianShape(relativeSpeedPosterior.maximumValue, speedDecayWidth, relativeAmount);
andrew@0 503 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
andrew@0 504 relativeSpeedPosterior.renormalise();
andrew@0 505 */
andrew@0 506
andrew@0 507
andrew@0 508
andrew@0 509 }
andrew@0 510
andrew@0 511 void BayesianArrayStructure::setLikelihoodToConstant(){
andrew@0 512 //set new likelihood
andrew@0 513 relativeSpeedLikelihood.zero();
andrew@0 514 relativeSpeedLikelihood.addConstant(speedLikelihoodNoise);
andrew@0 515 }
andrew@0 516
andrew@0 517
andrew@0 518 void BayesianArrayStructure::updateTempoLikelihood(const double& speedRatio, const double& matchFactor){
andrew@0 519
andrew@0 520 //speedratio is speed of played relative to the recording
andrew@0 521
andrew@0 522 double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
andrew@0 523 // printf("index of likelihood would be %f for ratio %f\n", index, speedRatio);
andrew@0 524 if (index >= 0 && index < relativeSpeedPrior.length){
andrew@0 525 relativeSpeedLikelihood.addGaussianShape(index , relativeSpeedLikelihoodStdDev, matchFactor);
andrew@0 526 }
andrew@0 527 }
andrew@0 528
andrew@0 529
andrew@0 530
andrew@0 531 void BayesianArrayStructure::updateTempoDistribution(){
andrew@0 532
andrew@0 533 //copy posterior to prior
andrew@0 534 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 535
andrew@0 536 //update
andrew@0 537 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
andrew@0 538
andrew@0 539 //normalise
andrew@0 540 relativeSpeedPosterior.renormalise();
andrew@0 541
andrew@0 542 relativeSpeedPosterior.getMaximum();
andrew@0 543
andrew@0 544 //relativeSpeedPosterior.updateIntegratedEstimate(); - could be swayed when off to side
andrew@0 545 //so now limited to where there is room sround the MAP estimate
andrew@0 546 relativeSpeedPosterior.updateLimitedIntegratedEstimate();
andrew@0 547
andrew@0 548 speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
andrew@0 549 }
andrew@0 550
andrew@0 551
andrew@0 552 void BayesianArrayStructure::calculateTempoUpdate(){
andrew@0 553 //copy posterior to prior
andrew@0 554 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 555
andrew@0 556 //update
andrew@0 557 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
andrew@0 558
andrew@0 559 //normalise
andrew@0 560 relativeSpeedPosterior.renormalise();
andrew@0 561
andrew@0 562 relativeSpeedPosterior.getMaximum();
andrew@0 563
andrew@0 564 }
andrew@0 565
andrew@0 566
andrew@0 567 void BayesianArrayStructure::drawArrays(){
andrew@0 568
andrew@0 569 //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
andrew@0 570 //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
andrew@0 571
andrew@0 572 int displaySize = prior.arraySize;
andrew@0 573 ofSetColor(0,0,255);
andrew@0 574 prior.drawVector(0, displaySize);
andrew@0 575 ofSetColor(0,255,0);
andrew@0 576 likelihood.drawVector(0, displaySize);
andrew@0 577 ofSetColor(255,0,255);
andrew@0 578 posterior.drawVector(0, displaySize);
andrew@0 579
andrew@0 580
andrew@0 581
andrew@0 582 }
andrew@0 583
andrew@0 584
andrew@0 585 void BayesianArrayStructure::drawTempoArrays(){
andrew@0 586 ofSetColor(0,0,255);
andrew@0 587 // relativeSpeedPrior.drawVector(0, relativeSpeedPrior.arraySize);
andrew@0 588
andrew@0 589 ofSetColor(0,150,255);
andrew@0 590 relativeSpeedLikelihood.drawVector(0, relativeSpeedLikelihood.arraySize);
andrew@0 591
andrew@0 592 // relativeSpeedLikelihood.drawConstrainedVector(0, 199, 0, 1000);// relativeSpeedLikelihood.arraySize);
andrew@0 593 ofSetColor(255,0,0);
andrew@0 594 relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize);
andrew@0 595
andrew@0 596 // ofSetColor(0,0,255);
andrew@0 597 // tmpPosteriorForStorage.drawVector(0, tmpPosteriorForStorage.arraySize);
andrew@0 598
andrew@0 599 ofSetColor(255,255, 255);
andrew@0 600 ofLine(screenWidth/2, 0, screenWidth/2, ofGetHeight());//middle of screen
andrew@0 601
andrew@0 602 ofSetColor(25, 0, 250);
andrew@0 603 double fractionOfScreen = ((double)relativeSpeedPosterior.integratedEstimate / relativeSpeedPosterior.length);
andrew@0 604 ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
andrew@0 605
andrew@0 606 ofSetColor(255, 0, 20);
andrew@0 607 fractionOfScreen = ((double)relativeSpeedPosterior.MAPestimate / relativeSpeedPosterior.length);
andrew@0 608 ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
andrew@0 609
andrew@0 610
andrew@0 611 }
andrew@0 612
andrew@0 613
andrew@0 614 void BayesianArrayStructure::drawArraysRelativeToTimeframe(const double& startTimeMillis, const double& endTimeMillis){
andrew@0 615
andrew@0 616 screenWidth = ofGetWidth();
andrew@0 617
andrew@0 618 int startArrayIndex = 0;
andrew@0 619
andrew@0 620 if (prior.getIndexInRealTerms(prior.arraySize-1) > startTimeMillis){
andrew@0 621 //i.e. the array is on the page
andrew@0 622
andrew@0 623 while (prior.getIndexInRealTerms(startArrayIndex) < startTimeMillis){
andrew@0 624 startArrayIndex++;
andrew@0 625 }
andrew@0 626 int endArrayIndex = prior.arraySize-1;
andrew@0 627 //could find constraints here
andrew@0 628 if (prior.getIndexInRealTerms(prior.arraySize-1) > endTimeMillis)
andrew@0 629 endArrayIndex = (floor)((endTimeMillis - prior.offset)/prior.scalar);
andrew@0 630
andrew@0 631 //so we need to figure where start and end array are on screen
andrew@0 632 int startScreenPosition, endScreenPosition;
andrew@0 633 double screenWidthMillis = endTimeMillis - startTimeMillis;
andrew@0 634
andrew@0 635 startScreenPosition = (prior.getIndexInRealTerms(startArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
andrew@0 636 endScreenPosition = (double)(prior.getIndexInRealTerms(endArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
andrew@0 637
andrew@0 638 ofSetColor(0,0,100);
andrew@0 639 string relativeString = " offset "+ofToString(prior.offset, 1);//starttimes("+ofToString(startTimeMillis)+", "+ofToString(endTimeMillis);
andrew@0 640 relativeString += ": index "+ofToString(startArrayIndex)+" , "+ofToString(endArrayIndex)+" [";
andrew@0 641 // relativeString += ofToString(prior.getIndexInRealTerms(endArrayIndex), 3)+"] (sc-width:"+ofToString(screenWidthMillis, 1)+") ";
andrew@0 642 relativeString += " mapped to screen "+ofToString(startScreenPosition)+" , "+ofToString(endScreenPosition);
andrew@0 643 // ofDrawBitmapString(relativeString, 100, 180);
andrew@0 644
andrew@0 645
andrew@0 646
andrew@0 647 ofSetColor(100,100,100);//255, 255, 0);
andrew@0 648 likelihood.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 649
andrew@0 650 // ofSetColor(0,0,200);
andrew@0 651 ofSetColor(170,170,170);//00,200);
andrew@0 652 prior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 653
andrew@0 654 ofSetColor(0,0,150);
andrew@0 655 // ofSetColor(200, 0, 0);
andrew@0 656 posterior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 657
andrew@0 658
andrew@0 659 // ofSetColor(0, 200, 255);
andrew@0 660 // acceleration.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
andrew@0 661
andrew@0 662
andrew@0 663 }
andrew@0 664
andrew@0 665 }
andrew@0 666
andrew@0 667
andrew@6 668 void BayesianArrayStructure::printPostOffset(){
andrew@6 669 double tmp = posterior.getMAPestimate();
andrew@6 670 printf(" MAP index %i post offset %f == %f ms\n", posterior.MAPestimate, posterior.offset, posterior.getIndexInRealTerms(posterior.MAPestimate));
andrew@6 671 }
andrew@6 672
andrew@10 673 //PROJECT PRIOR CODE
andrew@11 674
andrew@11 675 void BayesianArrayStructure::projectDistribution(const double& newEventTime, const double& newAlignmentPosition, DynamicVector& projectedPrior){
andrew@10 676
andrew@10 677 projectedPrior.copyFromDynamicVector(posterior);
andrew@10 678
andrew@10 679 double timeDifference = newEventTime - lastEventTime;
andrew@10 680
andrew@10 681 // if (timeDifference > 50 && updatingSpeedDistribution){
andrew@10 682 // addGaussianNoiseToSpeedPosterior(timeDifference * 10.0 / 100.);
andrew@10 683 // }
andrew@10 684
andrew@10 685
andrew@11 686 // updateBestEstimate(timeDifference);
andrew@11 687 // lastBestEstimateUpdateTime = newEventTime;//getTimeNow(timePlayed);
andrew@10 688
andrew@10 689 //set TARGETS - commented tenmporarily
andrew@11 690
andrew@11 691 //setNewDistributionOffsets(max(0., bestEstimate - (prior.scalar*prior.arraySize/2)));
andrew@11 692 projectedPrior.offset = posterior.offset;//max(0., newAlignmentPosition - (projectedPrior.scalar*projectedPrior.arraySize/2));
andrew@11 693
andrew@11 694 // int timeDifference = newEventTime - lastEventTime;
andrew@11 695
andrew@11 696 double timeDifferenceInPositionVectorUnits = timeDifference / projectedPrior.scalar;
andrew@11 697
andrew@11 698 // printf("CROSS UPDATE time diff %f ms is %f units; ", timeDifference, timeDifferenceInPositionVectorUnits);
andrew@11 699 projectedPrior.zero();//kill prior
andrew@11 700
andrew@11 701 // calculateNewPriorOffset(timeDifference);//dioesnt do anything
andrew@11 702
andrew@11 703 // printf("new prior offset %f and post offset %f\n", prior.offset, posterior.offset);
andrew@11 704
andrew@11 705 if (timeDifferenceInPositionVectorUnits > crossUpdateTimeThreshold)
andrew@11 706 complexCrossUpdateProjection(projectedPrior, timeDifferenceInPositionVectorUnits);
andrew@11 707 else
andrew@11 708 translatePosteriorByMaximumSpeed(projectedPrior, timeDifferenceInPositionVectorUnits);
andrew@11 709
andrew@11 710
andrew@11 711 // updateCounter++;
andrew@11 712 projectedPrior.renormalise();//not strictly necessary??
andrew@11 713
andrew@11 714
andrew@10 715 //i.e. using the same offset as prior
andrew@11 716 // posterior.offset = prior.offset;//
andrew@10 717
andrew@10 718 // float tmpPrior = max(0., bestEstimate - (prior.scalar*prior.arraySize/2));// prior.offset = max(0., bestEstimate - (prior.scalar*prior.arraySize/2));
andrew@10 719 // printf("Using prior offset of %f not %f\n", tmpPrior, prior.offset);
andrew@10 720
andrew@11 721 // lastEventTime = newEventTime;//lastEventTime = ofGetElapsedTimeMillis();
andrew@10 722
andrew@10 723 }
andrew@10 724
andrew@10 725
andrew@10 726
andrew@11 727 void BayesianArrayStructure::complexCrossUpdateProjection(DynamicVector& projectedPrior, const double& timeDifferenceInPositionVectorUnits){
andrew@10 728
andrew@10 729 int distanceMoved, newPriorIndex;
andrew@11 730
andrew@10 731 double speedValue = relativeSpeedPosterior.offset;
andrew@10 732
andrew@10 733 for (int i = 0;i < relativeSpeedPosterior.arraySize;i++){
andrew@10 734
andrew@10 735 distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
andrew@10 736
andrew@10 737 if (relativeSpeedPosterior.array[i] != 0){
andrew@10 738
andrew@10 739 double speedContribution = relativeSpeedPosterior.array[i];
andrew@10 740
andrew@11 741 newPriorIndex = posterior.offset - projectedPrior.offset + distanceMoved;//i.e. where post[0] goes to in terms of prior at this speed
andrew@10 742 int postIndex = 0;//index of posterior that will contribute
andrew@10 743
andrew@11 744 while (postIndex < posterior.arraySize && newPriorIndex < projectedPrior.arraySize){
andrew@11 745
andrew@10 746 //would use this method
andrew@10 747 //newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
andrew@10 748
andrew@10 749 if (newPriorIndex >= 0){
andrew@11 750 projectedPrior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
andrew@10 751 // 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@10 752 }
andrew@10 753 //but we actually do this for simplicity
andrew@10 754 newPriorIndex++;
andrew@10 755 postIndex++;
andrew@10 756 }//end for. now while
andrew@10 757
andrew@10 758
andrew@10 759 }//if not zero
andrew@10 760
andrew@10 761 speedValue += relativeSpeedPosterior.scalar;//optimised line
andrew@10 762 //as we wanted:
andrew@10 763 // double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
andrew@10 764
andrew@10 765 }//end speed
andrew@11 766
andrew@10 767 }
andrew@10 768
andrew@10 769
andrew@10 770
andrew@11 771 void BayesianArrayStructure::translatePosteriorByMaximumSpeed(DynamicVector& translatedPosterior, const double& timeDifferenceInPositionVectorUnits){
andrew@10 772
andrew@10 773
andrew@10 774 int distanceMoved, newPriorIndex;
andrew@10 775 double speedIndex = getSpeedEstimateIndex();
andrew@10 776 double speedValue = relativeSpeedPosterior.getIndexInRealTerms(speedIndex);
andrew@10 777
andrew@10 778 // double speedValue = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
andrew@10 779
andrew@10 780 //so for scalar 0.01, 50 -> speed value of 0.5
andrew@10 781 double speedContribution = relativeSpeedPosterior.array[(int)round(speedIndex)];
andrew@10 782 //so we have moved
andrew@10 783 distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
andrew@10 784
andrew@10 785 // printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits);
andrew@10 786
andrew@10 787 for (int postIndex = 0;postIndex < posterior.arraySize;postIndex++){
andrew@10 788 //old posterior contributing to new prior
andrew@10 789 newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
andrew@10 790 if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
andrew@11 791 translatedPosterior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
andrew@10 792 }
andrew@10 793
andrew@10 794 }
andrew@10 795
andrew@10 796 }
andrew@11 797
andrew@10 798
andrew@10 799 //END PROJECT PRIOR CODE
andrew@10 800
andrew@10 801
andrew@11 802
andrew@0 803 /*
andrew@0 804
andrew@0 805 void BayesianArrayStructure::updateTempoDistribution(const double& speedRatio, const double& matchFactor){
andrew@0 806 //speedratio is speed of played relative to the recording
andrew@0 807
andrew@0 808 double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
andrew@0 809 // printf("\nindex of likelihood would be %f\n", index);
andrew@0 810 if (index >= 0 && index < relativeSpeedPrior.length){
andrew@0 811 //then we can do update
andrew@0 812
andrew@0 813 //set new likelihood
andrew@0 814 relativeSpeedLikelihood.zero();
andrew@0 815 relativeSpeedLikelihood.addConstant(speedLikelihoodNoise);
andrew@0 816
andrew@0 817 relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5*matchFactor);
andrew@0 818
andrew@0 819
andrew@0 820 //copy posterior to prior
andrew@0 821 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
andrew@0 822
andrew@0 823 //update
andrew@0 824 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
andrew@0 825
andrew@0 826 //normalise
andrew@0 827 relativeSpeedPosterior.renormalise();
andrew@0 828
andrew@0 829 relativeSpeedPosterior.getMaximum();
andrew@0 830 }//end if within range
andrew@0 831
andrew@0 832
andrew@0 833 }
andrew@0 834
andrew@0 835 */