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
|