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
|