annotate newOFsrc/bayesianArray.cpp @ 3:6565c7cb9c71

Added KL divergence and entropy
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Wed, 22 Feb 2012 22:29:43 +0000
parents c49a8f33afab
children 1ea18717ba7c
rev   line source
andrew@2 1 /*
andrew@2 2 * bayesianArray.cpp
andrew@2 3 * bayesianTest5
andrew@2 4 *
andrew@2 5 * Created by Andrew Robertson on 08/05/2010.
andrew@2 6 * Copyright 2010 __MyCompanyName__. All rights reserved.
andrew@2 7 *
andrew@2 8 */
andrew@2 9
andrew@2 10 #include "bayesianArray.h"
andrew@2 11 #include "math.h"
andrew@2 12 #include "ofMain.h"
andrew@2 13
andrew@2 14 bayesianArray::bayesianArray(){
andrew@2 15 likelihoodNoise = 0.5;
andrew@2 16 likelihoodMean = ARRAY_SIZE/2;
andrew@2 17 likelihoodStdDev = ARRAY_SIZE / 12;
andrew@2 18 initialiseArray();
andrew@2 19 }
andrew@2 20
andrew@2 21 void bayesianArray::initialiseArray(){
andrew@2 22
andrew@2 23 //maximumIndex = 12;//change this
andrew@2 24 setGaussianPrior(ARRAY_SIZE/2, ARRAY_SIZE/1);
andrew@2 25 setGaussianLikelihood(ARRAY_SIZE/2, ARRAY_SIZE/1);//likelihoodMean, likelihoodStdDev);
andrew@2 26
andrew@2 27 calculatePosterior();
andrew@2 28 renormalisePosterior();
andrew@2 29 posteriorDecayRate = 0.06;
andrew@2 30
andrew@2 31 eighthNoteProportion = 0.35;//must be less than 0.5 to discriminate - was 0.4
andrew@2 32 earlySixteenthNoteProportion = 0;
andrew@2 33 lateSixteenthNoteProportion = 0;
andrew@2 34 decayNoiseAmount = 0.1;
andrew@2 35 decayNoiseStdDev = ARRAY_SIZE/24;
andrew@2 36 standardDeviation = likelihoodStdDev;
andrew@2 37 setDecayNoiseGaussian(ARRAY_SIZE/2, decayNoiseStdDev);
andrew@2 38
andrew@2 39 setGaussianLikelihood(likelihoodMean, likelihoodStdDev);
andrew@2 40 }
andrew@2 41
andrew@2 42
andrew@2 43 void bayesianArray::setGaussianPrior(float mean, float StdDev){
andrew@2 44 int i;
andrew@2 45 for (i=0;i<ARRAY_SIZE;i++){
andrew@2 46 prior[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
andrew@2 47 //posterior[i] = prior[i];
andrew@2 48 }
andrew@2 49 }
andrew@2 50
andrew@2 51 void bayesianArray::setGaussianPosterior(float mean, float StdDev){
andrew@2 52 int i;
andrew@2 53 for (i=0;i<ARRAY_SIZE;i++){
andrew@2 54 posterior[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
andrew@2 55 }
andrew@2 56 }
andrew@2 57
andrew@2 58 void bayesianArray::setGaussianLikelihoodForBeats(float mean, float StdDev){
andrew@2 59 //this has eighth and sixteenth positions included
andrew@2 60
andrew@2 61 if (mean >= 0 && mean <= ARRAY_SIZE){
andrew@2 62 int i; float eighthDifference;
andrew@2 63 int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE;
andrew@2 64 int earlySixteenthPosition = ((int)mean + (3*ARRAY_SIZE/4))%ARRAY_SIZE;;
andrew@2 65 int lateSixteenthPosition = ((int)mean + (ARRAY_SIZE/4))%ARRAY_SIZE;;
andrew@2 66
andrew@2 67 float mainDifference, sixteenthDifference;
andrew@2 68 float gaussianProportion = 1 - likelihoodNoise;
andrew@2 69 float mainProportion = (1 - eighthNoteProportion - earlySixteenthNoteProportion - lateSixteenthNoteProportion);
andrew@2 70
andrew@2 71 for (i=0;i < ARRAY_SIZE;i++){
andrew@2 72
andrew@2 73 mainDifference = min( fabs(i-mean) , (double)(i + ARRAY_SIZE - mean));
andrew@2 74 likelihood[i] = gaussianProportion * mainProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ;
andrew@2 75
andrew@2 76 eighthDifference = min( abs(i - eighthPosition) , i + ARRAY_SIZE - eighthPosition);
andrew@2 77 eighthDifference = min(eighthDifference , (float)(ARRAY_SIZE + eighthPosition - i ));
andrew@2 78 //for e.g. +0.43, or -0.47 we require the gaussian around the half note too
andrew@2 79 likelihood[i] += gaussianProportion * eighthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(eighthDifference)*(eighthDifference)/(2*StdDev*StdDev)) ;
andrew@2 80
andrew@2 81 sixteenthDifference = min( abs(i - earlySixteenthPosition) , i + ARRAY_SIZE - earlySixteenthPosition);
andrew@2 82 sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + earlySixteenthPosition - i ));
andrew@2 83 //for e.g. +0.43, or -0.47 we require the gaussian around the half note too
andrew@2 84 likelihood[i] += gaussianProportion * earlySixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ;
andrew@2 85
andrew@2 86 sixteenthDifference = min( abs(i - lateSixteenthPosition) , i + ARRAY_SIZE - lateSixteenthPosition);
andrew@2 87 sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + lateSixteenthPosition - i ));
andrew@2 88 //for e.g. +0.43, or -0.47 we require the gaussian around the half note too
andrew@2 89 likelihood[i] += gaussianProportion * lateSixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ;
andrew@2 90
andrew@2 91
andrew@2 92
andrew@2 93 likelihood[i] += (likelihoodNoise / ARRAY_SIZE);
andrew@2 94 //likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) ,
andrew@2 95 //(double) (likelihoodNoise / ARRAY_SIZE) );
andrew@2 96 }
andrew@2 97 // renormaliseArray(&likelihood[0], ARRAY_SIZE);
andrew@2 98 }//end if mean within limits
andrew@2 99 }
andrew@2 100
andrew@2 101
andrew@2 102 void bayesianArray::setGaussianLikelihood(float mean, float StdDev){
andrew@2 103 if (mean >= 0 && mean <= ARRAY_SIZE){
andrew@2 104 int i; float eighthDifference;
andrew@2 105 int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE;
andrew@2 106 float mainDifference;
andrew@2 107 float gaussianProportion = 1 - likelihoodNoise;
andrew@2 108
andrew@2 109 for (i=0;i < ARRAY_SIZE;i++){
andrew@2 110
andrew@2 111 mainDifference = min( fabs(i-mean) , (double)(i + ARRAY_SIZE - mean));
andrew@2 112 //without * (1 - eighthNoteProportion)
andrew@2 113 likelihood[i] = gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ;
andrew@2 114
andrew@2 115 likelihood[i] += (likelihoodNoise / ARRAY_SIZE);
andrew@2 116 //likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) ,
andrew@2 117 //(double) (likelihoodNoise / ARRAY_SIZE) );
andrew@2 118 }
andrew@2 119 // renormaliseArray(&likelihood[0], ARRAY_SIZE);
andrew@2 120 }//end if mean within limits
andrew@2 121 }
andrew@2 122
andrew@2 123 void bayesianArray::calculatePosterior(){
andrew@2 124 int i;
andrew@2 125 for (i=0;i < ARRAY_SIZE;i++){
andrew@2 126 posterior[i] = likelihood[i] * prior[i];
andrew@2 127 }
andrew@2 128 //renormalisePosterior();
andrew@2 129 }
andrew@2 130
andrew@2 131
andrew@2 132 float bayesianArray::getMaximum(float *ptr, int length){
andrew@2 133 int i;
andrew@2 134 float max = 0;
andrew@2 135 for (i=0;i < length;i++){
andrew@2 136 if (*(ptr+i)>max)
andrew@2 137 max = *(ptr+i);
andrew@2 138 }
andrew@2 139 maximumValue = max;
andrew@2 140 return max;
andrew@2 141 }
andrew@2 142
andrew@2 143 float* bayesianArray::getMaximumEstimate(float *ptr, int length){
andrew@2 144 float returnArray[2];
andrew@2 145 int i;
andrew@2 146 float max = 0;
andrew@2 147 maximumIndex = 0;
andrew@2 148 for (i=0;i < length;i++){
andrew@2 149 if (*(ptr+i)>max){
andrew@2 150 max = *(ptr+i);
andrew@2 151 maximumIndex = i;
andrew@2 152 }
andrew@2 153 }
andrew@2 154 returnArray[0] = max;
andrew@2 155 returnArray[1] = maximumIndex;
andrew@2 156 maximumValue = max;
andrew@2 157 return &returnArray[0];
andrew@2 158 }
andrew@2 159
andrew@2 160
andrew@2 161
andrew@2 162 double bayesianArray::getIntegratedEstimateIndex(){
andrew@2 163 int i;
andrew@2 164 float integratedQuantity = 0;
andrew@2 165 float integratedTotal = 0;
andrew@2 166 double integratedIndex = 0;
andrew@2 167 for (i=0;i < ARRAY_SIZE;i++){
andrew@2 168 integratedQuantity += posterior[i];//the values of the probability distribution
andrew@2 169 integratedTotal += i*posterior[i];
andrew@2 170 }
andrew@2 171 if (integratedQuantity > 0){
andrew@2 172 integratedIndex = integratedTotal / integratedQuantity;
andrew@2 173 }
andrew@2 174 integratedEstimate = (float) integratedIndex;
andrew@2 175 return integratedIndex;
andrew@2 176 }
andrew@2 177
andrew@2 178
andrew@2 179 double bayesianArray::calculateStandardDeviation(){
andrew@2 180
andrew@2 181 double total = 0;
andrew@2 182 double pdfSum;
andrew@2 183 double variance = 0;
andrew@2 184 for (int i=0;i < ARRAY_SIZE;i++){
andrew@2 185 //*posterior[i] *
andrew@2 186 total += posterior[i] * (i - integratedEstimate) * (i - integratedEstimate);//the values of the probability distribution
andrew@2 187 pdfSum += posterior[i];
andrew@2 188 }
andrew@2 189
andrew@2 190 if (pdfSum > 0)
andrew@2 191 variance = total / pdfSum;
andrew@2 192 else
andrew@2 193 variance = ARRAY_SIZE;
andrew@2 194
andrew@2 195 standardDeviation = sqrt(variance);
andrew@2 196 return standardDeviation;
andrew@2 197 }
andrew@2 198
andrew@2 199
andrew@2 200
andrew@2 201 void bayesianArray::renormaliseArray(float *ptr, int length){
andrew@2 202 int i;
andrew@2 203 float totalArea = 0;
andrew@2 204 for (i=0;i < length;i++){
andrew@2 205 totalArea += *(ptr+i);
andrew@2 206 }
andrew@2 207
andrew@2 208 for (i=0;i < length;i++){
andrew@2 209 *(ptr+i) /= totalArea;
andrew@2 210 }
andrew@2 211
andrew@2 212 }
andrew@2 213
andrew@2 214 void bayesianArray::resetPrior(){
andrew@2 215 int i;
andrew@2 216 for (i=0;i<ARRAY_SIZE;i++){
andrew@2 217 prior[i] = posterior[i];
andrew@2 218 }
andrew@2 219 }
andrew@2 220
andrew@2 221 void bayesianArray::renormalisePrior(){
andrew@2 222 int i;
andrew@2 223 float totalArea = 0;
andrew@2 224 for (i=0;i < ARRAY_SIZE;i++){
andrew@2 225 totalArea += prior[i];
andrew@2 226 }
andrew@2 227
andrew@2 228 for (i=0;i < ARRAY_SIZE;i++){
andrew@2 229 prior[i] /= totalArea;
andrew@2 230 }
andrew@2 231 }
andrew@2 232
andrew@2 233 void bayesianArray::renormalisePosterior(){
andrew@2 234 int i;
andrew@2 235 float totalArea = 0;
andrew@2 236 for (i=0;i < ARRAY_SIZE;i++){
andrew@2 237 totalArea += posterior[i];
andrew@2 238 }
andrew@2 239
andrew@2 240 for (i=0;i < ARRAY_SIZE;i++){
andrew@2 241 posterior[i] /= totalArea;
andrew@2 242 }
andrew@2 243 }
andrew@2 244
andrew@2 245 void bayesianArray::decayPosterior(){
andrew@2 246 float *pointer;
andrew@2 247 pointer = getMaximumEstimate(&posterior[0], ARRAY_SIZE);
andrew@2 248 float maximum;
andrew@2 249 maximum = *pointer;
andrew@2 250 int i;
andrew@2 251 for (i=0;i<ARRAY_SIZE;i++){
andrew@2 252 posterior[i] += (maximum - posterior[i]) * posteriorDecayRate * 0.01;;//usded to be * maximum not minus value
andrew@2 253 }
andrew@2 254 maximumIndex = *(pointer+1);
andrew@2 255 }
andrew@2 256
andrew@2 257 void bayesianArray::setDecayNoiseGaussian(float mean, float StdDev){
andrew@2 258 int i;
andrew@2 259 for (i=0;i<ARRAY_SIZE;i++){
andrew@2 260 decayNoiseArray[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev));
andrew@2 261 }
andrew@2 262 }
andrew@2 263
andrew@2 264 void bayesianArray::decayPosteriorWithGaussianNoise(){
andrew@2 265
andrew@2 266 int i;
andrew@2 267 float currentMaximum = getMaximum(&posterior[0], ARRAY_SIZE);
andrew@2 268 for (i=0;i<ARRAY_SIZE;i++){
andrew@2 269 posterior[i] += decayNoiseArray[(i - (int)maximumIndex + ((3*ARRAY_SIZE)/2)) % ARRAY_SIZE] * currentMaximum * decayNoiseAmount;
andrew@2 270 //posteriorDecayRate * 0.01;;//usded to be * maximum not minus value
andrew@2 271 }
andrew@2 272
andrew@2 273 }
andrew@2 274
andrew@2 275 void bayesianArray::resetMaximumPosterior(){
andrew@2 276 int i;
andrew@2 277 float max = 0;
andrew@2 278 for (i=0;i < ARRAY_SIZE;i++){
andrew@2 279 if (posterior[i]>max){
andrew@2 280 maximumIndex = i;
andrew@2 281 max = posterior[i];
andrew@2 282 }
andrew@2 283 }
andrew@2 284 }
andrew@2 285
andrew@2 286 void bayesianArray::translateDistribution(int translationIndex){
andrew@2 287 int tmpIndex;
andrew@2 288 //copy array
andrew@2 289 int i;
andrew@2 290 for (i=0;i < ARRAY_SIZE;i++){
andrew@2 291 tempPosteriorArray[i] = posterior[i] ;
andrew@2 292 }
andrew@2 293 //translate values
andrew@2 294 for (i=0;i < ARRAY_SIZE;i++){
andrew@2 295 tmpIndex = (i + translationIndex + ARRAY_SIZE)%ARRAY_SIZE;
andrew@2 296 posterior[tmpIndex] = tempPosteriorArray[i];
andrew@2 297 }
andrew@2 298 //now delete tmp array
andrew@2 299 }
andrew@2 300
andrew@2 301 double bayesianArray::getKLdivergence(){
andrew@2 302 double KLsum = 0;
andrew@2 303 //take no chances - renormalise both prior and posterior
andrew@2 304 renormalisePosterior();
andrew@2 305 renormalisePrior();
andrew@2 306 for (int i = 0;i < ARRAY_SIZE;i++){
andrew@2 307 if (posterior[i] > 0 && prior[i] > 0){
andrew@2 308 KLsum += (posterior[i]*log(posterior[i]/prior[i]));
andrew@2 309 }
andrew@2 310 }
andrew@2 311 return KLsum;
andrew@2 312 }
andrew@2 313
andrew@3 314 double bayesianArray::getEntropyOfPosterior(){
andrew@3 315 double entropy = 0;
andrew@3 316 for (int i = 0;i < ARRAY_SIZE;i++){
andrew@3 317 if (posterior[i] > 0){
andrew@3 318 entropy += posterior[i]*log(posterior[i]);
andrew@3 319 }
andrew@3 320 }
andrew@3 321 return -1*entropy;
andrew@3 322 }
andrew@3 323
andrew@3 324