Mercurial > hg > midi-score-follower
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/BayesianArrayStructure.cpp Tue Aug 16 11:29:59 2011 +0100 @@ -0,0 +1,386 @@ +/* + * BayesianArrayStructure.cpp + * midiCannamReader + * + * Created by Andrew on 17/07/2011. + * Copyright 2011 QMUL. All rights reserved. + * + */ + +#include "BayesianArrayStructure.h" + +BayesianArrayStructure::BayesianArrayStructure(){ + printf("Bayesian structure: DeFault constructor called"); + + prior.createVector(1); + likelihood.createVector(1); + posterior.createVector(1); + + + tmpPrior.createVector(240); + tmpPrior.addGaussianShape(100, 40, 1); + tmpPrior.addGaussianShape(200, 10, 0.2); + tmpPrior.translateDistribution(20); + + lastEventTime = ofGetElapsedTimeMillis(); + + speedDecayWidth = 20; + speedDecayAmount = 10; +} + +BayesianArrayStructure::BayesianArrayStructure(int length){ + printf("BAYESIAN STURTUCRE CREATED LENGTH: %i\n", length); + //this constructor isnt called it seems + prior.createVector(length); + likelihood.createVector(length); + posterior.createVector(length); + +} + + + +void BayesianArrayStructure::resetSize(int length){ + printf("BAYESIAN STRUCTURE size is : %i\n", length); + + prior.createVector(length); + likelihood.createVector(length); + posterior.createVector(length); + + acceleration.createVector(length); + +} + + + +void BayesianArrayStructure::resetSpeedToOne(){ + relativeSpeedPrior.zero(); + relativeSpeedPosterior.zero(); + relativeSpeedLikelihood.zero(); + + relativeSpeedPosterior.addGaussianShape(40, 5, 0.6); + + relativeSpeedPosterior.addGaussianShape(100, 5, 0.8); + relativeSpeedPosterior.renormalise(); + relativeSpeedPosterior.getMaximum(); + + acceleration.addGaussianShape(2000, 20, 0.8); + +} + +void BayesianArrayStructure::resetSpeedSize(int length){ + printf("BAYESIAN SPEED size is : %i\n", length); + + relativeSpeedPrior.createVector(length); + relativeSpeedLikelihood.createVector(length); + relativeSpeedPosterior.createVector(length); + + + +} +void BayesianArrayStructure::setRelativeSpeedScalar(double f){ + relativeSpeedPrior.scalar = f; + relativeSpeedPosterior.scalar = f; + relativeSpeedLikelihood.scalar = f; +} + +void BayesianArrayStructure::simpleExample(){ + //simple example + prior.addGaussianShape(50, 10, 1); + prior.addGaussianShape(150, 30, 0.3); + prior.addGaussianShape(250, 30, 0.2); + + likelihood.addGaussianShape(90, 20, 0.6); + likelihood.addConstant(0.02); + posterior.doProduct(prior, likelihood); + +// relativeSpeedPosterior.addToIndex(100, 1); +// relativeSpeedPosterior.addToIndex(40, 0.7); + relativeSpeedPosterior.addGaussianShape(100, 20, 1); +// relativeSpeedPosterior.addGaussianShape(10, 2, 0.5); + relativeSpeedPosterior.getMaximum(); + +} + +void BayesianArrayStructure::copyPriorToPosterior(){ + + for (int i = 0;i < prior.arraySize;i++){ + posterior.array[i] = prior.array[i]; + } +} + +void BayesianArrayStructure::resetArrays(){ + prior.zero(); + likelihood.zero(); + prior.addGaussianShape(0, 80, 1); + likelihood.addConstant(1); + posterior.zero(); + posterior.addGaussianShape(0, 60, 1); + setNewDistributionOffsets(0); + bestEstimate = 0; +// lastBestEstimateUpdateTime = ofGetElapsedTimeMillis(); + +} + +void BayesianArrayStructure::updateBestEstimate(){ + double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//lastBestEstimateUpdateTime; + + bestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate); + // + //lastBestEstimateUpdateTime = ofGetElapsedTimeMillis(); +} + +void BayesianArrayStructure::calculatePosterior(){ + posterior.doProduct(prior, likelihood); + posterior.renormalise(); + + /* + int i; + for (i = 0;i < prior.length;i++){ + // printf("priori [%i] is %f\n", i, prior[i]); + *(posterior+i) = *(prior+i); + // posterior[i] = likelihood[i] * prior[i]; + } + */ + + +} + + + + +void BayesianArrayStructure::setNewDistributionOffsets(const double& newOffset){ + prior.offset = newOffset; + likelihood.offset = newOffset; +// posterior.offset = newOffset; +} + + +void BayesianArrayStructure::crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference){ + //set the cutoff for offset of position first! XXX + +// printf("time difference %f, ", timeDifference); + + double timeDifferenceInPositionVectorUnits = timeDifference / prior.scalar; + + prior.zero();//kill prior + calculateNewPriorOffset(timeDifference);//set new prior offset here + + for (int i = 0;i < speed.arraySize;i++){ +// printf("[%i] %f\n", i, speed.array[i]); + //set speed + double speedValue = speed.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5 + + //so we have moved + int distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value + + if (speed.array[i] != 0){ + + // printf("speed [%i] gives %f moved %i\n", i, speedValue, distanceMoved); + + for (int postIndex = 0;postIndex < position.arraySize;postIndex++){ + //old posterior contributing to new prior + int newPriorIndex = postIndex + position.offset - prior.offset + distanceMoved; + if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){ + prior.addToIndex(newPriorIndex, position.array[postIndex]*speed.array[i]); + // printf("adding [%i] : %f\n", newPriorIndex, posterior.array[postIndex]*speed.array[i]); + } + + } + + }//if not zero + }//end speed + + prior.renormalise(); + +} + +void BayesianArrayStructure::calculateNewPriorOffset(const double& timeDifference){ + + double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate); + // printf("Maxspeed is %f\n", maxSpeed); + + double priorMax = posterior.getMaximum(); + double distanceTravelled = maxSpeed * (timeDifference / prior.scalar); + double newMaxLocation = posterior.MAPestimate + distanceTravelled; + // printf("MAP: %i, tim df %f, distance %f, new location %f\n", posterior.MAPestimate, timeDifference, distanceTravelled, newMaxLocation); + +} + + +void BayesianArrayStructure::decaySpeedDistribution(double timeDifference){ + + // commented for the moment + double relativeAmount = max(1.0, timeDifference/1000.); +// printf("decay %f around %i \n", timeDifference, relativeSpeedPosterior.MAPestimate); + relativeAmount *= speedDecayAmount; + relativeSpeedPosterior.renormalise(); + relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, relativeAmount); + + relativeSpeedPosterior.renormalise(); + double newMax = relativeSpeedPosterior.getMaximum(); + + //old code +// relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, 10); + //relativeSpeedPosterior.addConstant(1); + + /* + relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior); + relativeSpeedLikelihood.zero(); + relativeSpeedLikelihood.addConstant(0.2); + relativeSpeedLikelihood.addGaussianShape(relativeSpeedPosterior.maximumValue, speedDecayWidth, relativeAmount); + relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood); + relativeSpeedPosterior.renormalise(); + */ + + + +} + +void BayesianArrayStructure::updateTempoDistribution(const double& speedRatio, const double& matchFactor){ + //speedratio is speed of played relative to the recording + + double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio); +// printf("\nindex of likelihood would be %f\n", index); + if (index >= 0 && index < relativeSpeedPrior.length){ + //then we can do update + + //set new likelihood + relativeSpeedLikelihood.zero(); + relativeSpeedLikelihood.addConstant(0.02); + + relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5*matchFactor); + + + //copy posterior to prior + relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior); + + //update + relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood); + + //normalise + relativeSpeedPosterior.renormalise(); + + relativeSpeedPosterior.getMaximum(); + }//end if within range + + +} + + +void BayesianArrayStructure::setFlatTempoLikelihood(){ //set new likelihood + relativeSpeedLikelihood.zero(); + relativeSpeedLikelihood.addConstant(0.3); +} + +void BayesianArrayStructure::updateTempoLikelihood(const double& speedRatio, const double& matchFactor){ + + double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio); + + if (index >= 0 && index < relativeSpeedPrior.length){ + relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5);//*matchFactor); + } +} + + +void BayesianArrayStructure::calculateTempoUpdate(){ + //copy posterior to prior + relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior); + + //update + relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood); + + //normalise + relativeSpeedPosterior.renormalise(); + + relativeSpeedPosterior.getMaximum(); + +} + + +void BayesianArrayStructure::drawArrays(){ + + //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200); + //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200); + + int displaySize = prior.arraySize; + ofSetColor(255,0,0); + prior.drawVector(0, displaySize); + ofSetColor(0,255,0); + likelihood.drawVector(0, displaySize); + ofSetColor(0,0,255); + posterior.drawVector(0, displaySize); + ofSetColor(255,255,0); + relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize); + +// ofSetColor(255,255,255); +// tmpPrior.drawVector(0,300); + +} + + +void BayesianArrayStructure::drawTempoArrays(){ + ofSetColor(0,255,255); + relativeSpeedPrior.drawVector(0, relativeSpeedPrior.arraySize); + + ofSetColor(255,0,255); + relativeSpeedLikelihood.drawVector(0, relativeSpeedLikelihood.arraySize); + + ofSetColor(255,255,0); + relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize); + + ofSetColor(255,255, 255); + ofLine(screenWidth/2, 0, screenWidth/2, ofGetHeight());//middle of screen + + ofSetColor(0, 255, 0); + double fractionOfScreen = ((double)relativeSpeedPosterior.MAPestimate / relativeSpeedPosterior.length); + ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight()); +} + + +void BayesianArrayStructure::drawArraysRelativeToTimeframe(const double& startTimeMillis, const double& endTimeMillis){ + + screenWidth = ofGetWidth(); + + int startArrayIndex = 0; + + if (prior.getIndexInRealTerms(prior.arraySize-1) > startTimeMillis){ + //i.e. the array is on the page + + while (prior.getIndexInRealTerms(startArrayIndex) < startTimeMillis){ + startArrayIndex++; + } + int endArrayIndex = prior.arraySize-1; + //could find constraints here + if (prior.getIndexInRealTerms(prior.arraySize-1) > endTimeMillis) + endArrayIndex = (floor)((endTimeMillis - prior.offset)/prior.scalar); + + //so we need to figure where start and end array are on screen + int startScreenPosition, endScreenPosition; + double screenWidthMillis = endTimeMillis - startTimeMillis; + + startScreenPosition = (prior.getIndexInRealTerms(startArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis; + endScreenPosition = (double)(prior.getIndexInRealTerms(endArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis; + + ofSetColor(0,0,100); + string relativeString = " offset "+ofToString(prior.offset, 1);//starttimes("+ofToString(startTimeMillis)+", "+ofToString(endTimeMillis); + relativeString += ": index "+ofToString(startArrayIndex)+" , "+ofToString(endArrayIndex)+" ["; +// relativeString += ofToString(prior.getIndexInRealTerms(endArrayIndex), 3)+"] (sc-width:"+ofToString(screenWidthMillis, 1)+") "; + relativeString += " mapped to screen "+ofToString(startScreenPosition)+" , "+ofToString(endScreenPosition); + ofDrawBitmapString(relativeString, 100, 180); + + ofSetColor(0, 200, 0); + likelihood.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); + + ofSetColor(0,0,200); + prior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); + + ofSetColor(200, 0, 0); + posterior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); + +// ofSetColor(0, 200, 255); +// acceleration.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); + + + } + +} \ No newline at end of file