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