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