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