view src/bayesianArray.cpp @ 12:e148d1534733 tip

adding new max player
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Fri, 09 Mar 2012 20:42:34 +0000
parents 0f9165f96bdb
children
line wrap: on
line source
/*
 *  bayesianArray.cpp
 *  bayesianTest5
 *
 *  Created by Andrew Robertson on 08/05/2010.
 *  Copyright 2010 __MyCompanyName__. All rights reserved.
 *
 */

#include "bayesianArray.h"
#include "math.h"
#include "ofMain.h"

bayesianArray::bayesianArray(){
	likelihoodNoise = 0.5;
	likelihoodMean = ARRAY_SIZE/2;
	likelihoodStdDev = ARRAY_SIZE / 12;
initialiseArray();
}

void bayesianArray::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 bayesianArray::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 bayesianArray::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 bayesianArray::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
}


void bayesianArray::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( 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 bayesianArray::calculatePosterior(){
int i;
	for (i=0;i < ARRAY_SIZE;i++){
	posterior[i] = likelihood[i] * prior[i];
	}
	//renormalisePosterior();
}


float bayesianArray::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* bayesianArray::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 bayesianArray::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 bayesianArray::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 bayesianArray::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 bayesianArray::resetPrior(){
	int i;
	for (i=0;i<ARRAY_SIZE;i++){
	prior[i] = posterior[i];
	}
}

void bayesianArray::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 bayesianArray::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 bayesianArray::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 bayesianArray::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 bayesianArray::resetMaximumPosterior(){
int i;
float max = 0;
	for (i=0;i < ARRAY_SIZE;i++){	
		if (posterior[i]>max){
		maximumIndex = i;
		max = posterior[i];
		}
	}
}

void bayesianArray::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
}