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