Mercurial > hg > bayesian-drum-tracker
view newOFsrc/bayesianArray.cpp @ 2:c49a8f33afab
adding new OF source
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Wed, 22 Feb 2012 22:16:48 +0000 |
parents | |
children | 6565c7cb9c71 |
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::renormalisePrior(){ int i; float totalArea = 0; for (i=0;i < ARRAY_SIZE;i++){ totalArea += prior[i]; } for (i=0;i < ARRAY_SIZE;i++){ prior[i] /= totalArea; } } 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 } double bayesianArray::getKLdivergence(){ double KLsum = 0; //take no chances - renormalise both prior and posterior renormalisePosterior(); renormalisePrior(); for (int i = 0;i < ARRAY_SIZE;i++){ if (posterior[i] > 0 && prior[i] > 0){ KLsum += (posterior[i]*log(posterior[i]/prior[i])); } } return KLsum; }