diff hackday/DynamicBayesianArray.cpp @ 28:49a5b023df1e

Hackday files comitted - version as demo'd at London hackday
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Mon, 05 Dec 2011 07:00:47 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hackday/DynamicBayesianArray.cpp	Mon Dec 05 07:00:47 2011 +0000
@@ -0,0 +1,326 @@
+/*
+ *  DynamicDynamicBayesianArray.cpp
+ *  midiCannamReader
+ *
+ *  Created by Andrew on 17/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "DynamicBayesianArray.h"
+#include "math.h"
+#include "ofMain.h"
+
+DynamicBayesianArray::DynamicBayesianArray(){
+	
+//	prior.createVector(240);
+//	likelihood.createVector(240);
+//	posterior.createVector(240);	
+	testVector.createVector(240);
+	testVector.addGaussianShape(100,10, 0.1);
+	
+	
+	likelihoodNoise = 0.5;
+	likelihoodMean = ARRAY_SIZE/2;
+	likelihoodStdDev = ARRAY_SIZE / 12;
+	initialiseArray();
+}
+
+void DynamicBayesianArray::initialiseArray(){
+	
+	//maximumIndex = 12;//change this
+	setGaussianPrior(ARRAY_SIZE/2, ARRAY_SIZE/1);	
+	setGaussianLikelihood(ARRAY_SIZE/2, ARRAY_SIZE/1);//likelihoodMean, likelihoodStdDev);
+	
+	calculatePosterior();
+	renormalisePosterior();
+	posteriorDecayRate = 0.06;
+	
+	eighthNoteProportion = 0.35;//must be less than 0.5 to discriminate - was 0.4
+	earlySixteenthNoteProportion = 0;
+	lateSixteenthNoteProportion = 0;
+	decayNoiseAmount = 0.1;
+	decayNoiseStdDev = ARRAY_SIZE/24;
+	standardDeviation = likelihoodStdDev;
+	setDecayNoiseGaussian(ARRAY_SIZE/2, decayNoiseStdDev);
+	
+	setGaussianLikelihood(likelihoodMean, likelihoodStdDev);
+}
+
+
+void DynamicBayesianArray::setGaussianPrior(float mean, float StdDev){
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		prior[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
+		//posterior[i] = prior[i];
+	}
+}
+
+void DynamicBayesianArray::setGaussianPosterior(float mean, float StdDev){
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		posterior[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
+	}
+}
+
+
+void DynamicBayesianArray::setGaussianLikelihood(float mean, float StdDev){
+	if (mean >= 0 && mean <= ARRAY_SIZE){
+		int i;	float eighthDifference;
+		int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE;
+		float mainDifference;
+		float gaussianProportion = 1 - likelihoodNoise;
+		
+		for (i=0;i < ARRAY_SIZE;i++){
+			
+			mainDifference = min( double(fabs(i-mean)) , (double)(i + ARRAY_SIZE - mean));
+			//without * (1 - eighthNoteProportion)
+			likelihood[i] = gaussianProportion  * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ;
+			
+			likelihood[i] += (likelihoodNoise / ARRAY_SIZE);
+			//likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) , 
+			//(double) (likelihoodNoise / ARRAY_SIZE) );
+		}
+		//	renormaliseArray(&likelihood[0], ARRAY_SIZE);
+	}//end if mean within limits
+}
+
+void DynamicBayesianArray::calculatePosterior(){
+	int i;
+	for (i=0;i < ARRAY_SIZE;i++){
+		posterior[i] = likelihood[i] * prior[i];
+	}
+	//renormalisePosterior();
+}
+
+
+float DynamicBayesianArray::getMaximum(float *ptr, int length){
+	int i;
+	float max = 0;
+	for (i=0;i < length;i++){	
+		if (*(ptr+i)>max)
+			max = *(ptr+i);
+	}
+	maximumValue = max;
+	return max;
+}
+
+float* DynamicBayesianArray::getMaximumEstimate(float *ptr, int length){
+	float returnArray[2];
+	int i;
+	float max = 0;
+	maximumIndex = 0;
+	for (i=0;i < length;i++){	
+		if (*(ptr+i)>max){
+			max = *(ptr+i);
+			maximumIndex = i;
+		}
+	}
+	returnArray[0] = max;
+	returnArray[1] = maximumIndex;
+	maximumValue = max;
+	return &returnArray[0];
+}
+
+
+
+double DynamicBayesianArray::getIntegratedEstimateIndex(){
+	int i;
+	float integratedQuantity = 0;
+	float integratedTotal = 0;
+	double integratedIndex = 0;
+	for (i=0;i < ARRAY_SIZE;i++){	
+		integratedQuantity += posterior[i];//the values of the probability distribution
+		integratedTotal += i*posterior[i];
+	}
+	if (integratedQuantity > 0){
+		integratedIndex = integratedTotal / integratedQuantity;
+	}
+	integratedEstimate = (float) integratedIndex;
+	return integratedIndex;
+}
+
+
+double DynamicBayesianArray::calculateStandardDeviation(){
+	
+	double total = 0;
+	double pdfSum;
+	double variance = 0;
+	for (int i=0;i < ARRAY_SIZE;i++){	
+		//*posterior[i] * 		
+		total += posterior[i] * (i - integratedEstimate) * (i - integratedEstimate);//the values of the probability distribution
+		pdfSum += posterior[i];
+	}
+	
+	if (pdfSum > 0)
+		variance = total / pdfSum;
+	else 
+		variance = ARRAY_SIZE;
+	
+	standardDeviation = sqrt(variance);
+	return standardDeviation;
+}
+
+
+
+void DynamicBayesianArray::renormaliseArray(float *ptr, int length){
+	int i;
+	float totalArea = 0;
+	for (i=0;i < length;i++){
+		totalArea += *(ptr+i);
+	}
+	
+	for (i=0;i < length;i++){
+		*(ptr+i) /= totalArea;
+	}
+	
+}
+
+void DynamicBayesianArray::resetPrior(){
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		prior[i] = posterior[i];
+	}
+}
+
+void DynamicBayesianArray::renormalisePosterior(){
+	int i;
+	float totalArea = 0;
+	for (i=0;i < ARRAY_SIZE;i++){
+		totalArea += posterior[i];
+	}
+	
+	for (i=0;i < ARRAY_SIZE;i++){
+		posterior[i] /= totalArea;
+	}
+	
+}
+
+void DynamicBayesianArray::decayPosterior(){
+	float *pointer;
+	pointer = getMaximumEstimate(&posterior[0], ARRAY_SIZE);	
+	float maximum;
+	maximum = *pointer;
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		posterior[i] += (maximum - posterior[i]) * posteriorDecayRate * 0.01;;//usded to be * maximum not minus value
+	}
+	maximumIndex = *(pointer+1);
+}
+
+void DynamicBayesianArray::setDecayNoiseGaussian(float mean, float StdDev){
+	int i;
+	for (i=0;i<ARRAY_SIZE;i++){
+		decayNoiseArray[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
+	}
+}
+
+void DynamicBayesianArray::decayPosteriorWithGaussianNoise(){
+	
+	int i;
+	float currentMaximum = getMaximum(&posterior[0], ARRAY_SIZE);
+	for (i=0;i<ARRAY_SIZE;i++){
+		posterior[i] += decayNoiseArray[(i - (int)maximumIndex + ((3*ARRAY_SIZE)/2)) % ARRAY_SIZE] * currentMaximum * decayNoiseAmount;
+		//posteriorDecayRate * 0.01;;//usded to be * maximum not minus value
+	}
+	
+}
+
+void DynamicBayesianArray::resetMaximumPosterior(){
+	int i;
+	float max = 0;
+	for (i=0;i < ARRAY_SIZE;i++){	
+		if (posterior[i]>max){
+			maximumIndex = i;
+			max = posterior[i];
+		}
+	}
+}
+
+void DynamicBayesianArray::translateDistribution(int translationIndex){
+	int tmpIndex;
+	//copy array
+	int i;
+	for (i=0;i < ARRAY_SIZE;i++){
+		tempPosteriorArray[i] =	posterior[i] ;
+	}
+	//translate values
+	for (i=0;i < ARRAY_SIZE;i++){
+		tmpIndex = (i + translationIndex + ARRAY_SIZE)%ARRAY_SIZE;
+		posterior[tmpIndex] = tempPosteriorArray[i]; 
+	}
+	//now delete tmp array
+}
+
+
+void DynamicBayesianArray::drawFloatArray(float* arrayToDraw, const int& minIndex, const int& maxIndex){
+	
+	if (minIndex >= 0){
+	
+		double stepSize = ofGetWidth() / (double)(maxIndex - minIndex);
+		double screenHeight = ofGetHeight();
+		double maxVal = getMaximum(&arrayToDraw[0], maxIndex);
+
+		for (int i = minIndex+1;i < maxIndex;i++){
+		
+			ofLine (stepSize*(i-1), screenHeight * (1 - arrayToDraw[i-1] / maxVal), stepSize*i, screenHeight * (1 - arrayToDraw[i] / maxVal) );
+		}
+	
+	}
+		
+		
+}
+
+ 
+
+/*
+void DynamicBayesianArray::drawDoubleArray(double[]& arrayToDraw, const int& minIndex, const int& maxIndex){
+
+	if (minIndex >= 0 && maxIndex <= arrayToDraw.size(0))
+
+}
+*/
+/*
+ void DynamicBayesianArray::setGaussianLikelihoodForBeats(float mean, float StdDev){
+ //this has eighth and sixteenth positions included
+ 
+ if (mean >= 0 && mean <= ARRAY_SIZE){
+ int i;	float eighthDifference;
+ int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE;
+ int earlySixteenthPosition = ((int)mean + (3*ARRAY_SIZE/4))%ARRAY_SIZE;;
+ int lateSixteenthPosition = ((int)mean + (ARRAY_SIZE/4))%ARRAY_SIZE;;
+ 
+ float mainDifference, sixteenthDifference;
+ float gaussianProportion = 1 - likelihoodNoise;
+ float mainProportion = (1 - eighthNoteProportion - earlySixteenthNoteProportion - lateSixteenthNoteProportion);
+ 
+ for (i=0;i < ARRAY_SIZE;i++){
+ 
+ mainDifference = min( fabs(i-mean) , (double)(i + ARRAY_SIZE - mean));
+ likelihood[i] = gaussianProportion * mainProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ;
+ 
+ eighthDifference = min( abs(i - eighthPosition) , i + ARRAY_SIZE - eighthPosition);
+ eighthDifference = min(eighthDifference , (float)(ARRAY_SIZE + eighthPosition - i ));
+ //for e.g. +0.43, or -0.47 we require the gaussian around the half note too
+ likelihood[i] += gaussianProportion * eighthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(eighthDifference)*(eighthDifference)/(2*StdDev*StdDev)) ;
+ 
+ sixteenthDifference = min( abs(i - earlySixteenthPosition) , i + ARRAY_SIZE - earlySixteenthPosition);
+ sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + earlySixteenthPosition - i ));
+ //for e.g. +0.43, or -0.47 we require the gaussian around the half note too
+ likelihood[i] += gaussianProportion * earlySixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ;
+ 
+ sixteenthDifference = min( abs(i - lateSixteenthPosition) , i + ARRAY_SIZE - lateSixteenthPosition);
+ sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + lateSixteenthPosition - i ));
+ //for e.g. +0.43, or -0.47 we require the gaussian around the half note too
+ likelihood[i] += gaussianProportion * lateSixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ;
+ 
+ 
+ 
+ likelihood[i] += (likelihoodNoise / ARRAY_SIZE);
+ //likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) , 
+ //(double) (likelihoodNoise / ARRAY_SIZE) );
+ }
+ //	renormaliseArray(&likelihood[0], ARRAY_SIZE);
+ }//end if mean within limits
+ }
+ */