Mercurial > hg > midi-score-follower
comparison src/BayesianArrayStructure.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 | 1a32ce016bb9 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:b299a65a3ad0 |
---|---|
1 /* | |
2 * BayesianArrayStructure.cpp | |
3 * midiCannamReader | |
4 * | |
5 * Created by Andrew on 17/07/2011. | |
6 * Copyright 2011 QMUL. All rights reserved. | |
7 * | |
8 */ | |
9 | |
10 #include "BayesianArrayStructure.h" | |
11 | |
12 BayesianArrayStructure::BayesianArrayStructure(){ | |
13 printf("Bayesian structure: DeFault constructor called"); | |
14 | |
15 prior.createVector(1); | |
16 likelihood.createVector(1); | |
17 posterior.createVector(1); | |
18 | |
19 | |
20 tmpPrior.createVector(240); | |
21 tmpPrior.addGaussianShape(100, 40, 1); | |
22 tmpPrior.addGaussianShape(200, 10, 0.2); | |
23 tmpPrior.translateDistribution(20); | |
24 | |
25 lastEventTime = ofGetElapsedTimeMillis(); | |
26 | |
27 speedDecayWidth = 20; | |
28 speedDecayAmount = 10; | |
29 } | |
30 | |
31 BayesianArrayStructure::BayesianArrayStructure(int length){ | |
32 printf("BAYESIAN STURTUCRE CREATED LENGTH: %i\n", length); | |
33 //this constructor isnt called it seems | |
34 prior.createVector(length); | |
35 likelihood.createVector(length); | |
36 posterior.createVector(length); | |
37 | |
38 } | |
39 | |
40 | |
41 | |
42 void BayesianArrayStructure::resetSize(int length){ | |
43 printf("BAYESIAN STRUCTURE size is : %i\n", length); | |
44 | |
45 prior.createVector(length); | |
46 likelihood.createVector(length); | |
47 posterior.createVector(length); | |
48 | |
49 acceleration.createVector(length); | |
50 | |
51 } | |
52 | |
53 | |
54 | |
55 void BayesianArrayStructure::resetSpeedToOne(){ | |
56 relativeSpeedPrior.zero(); | |
57 relativeSpeedPosterior.zero(); | |
58 relativeSpeedLikelihood.zero(); | |
59 | |
60 relativeSpeedPosterior.addGaussianShape(40, 5, 0.6); | |
61 | |
62 relativeSpeedPosterior.addGaussianShape(100, 5, 0.8); | |
63 relativeSpeedPosterior.renormalise(); | |
64 relativeSpeedPosterior.getMaximum(); | |
65 | |
66 acceleration.addGaussianShape(2000, 20, 0.8); | |
67 | |
68 } | |
69 | |
70 void BayesianArrayStructure::resetSpeedSize(int length){ | |
71 printf("BAYESIAN SPEED size is : %i\n", length); | |
72 | |
73 relativeSpeedPrior.createVector(length); | |
74 relativeSpeedLikelihood.createVector(length); | |
75 relativeSpeedPosterior.createVector(length); | |
76 | |
77 | |
78 | |
79 } | |
80 void BayesianArrayStructure::setRelativeSpeedScalar(double f){ | |
81 relativeSpeedPrior.scalar = f; | |
82 relativeSpeedPosterior.scalar = f; | |
83 relativeSpeedLikelihood.scalar = f; | |
84 } | |
85 | |
86 void BayesianArrayStructure::simpleExample(){ | |
87 //simple example | |
88 prior.addGaussianShape(50, 10, 1); | |
89 prior.addGaussianShape(150, 30, 0.3); | |
90 prior.addGaussianShape(250, 30, 0.2); | |
91 | |
92 likelihood.addGaussianShape(90, 20, 0.6); | |
93 likelihood.addConstant(0.02); | |
94 posterior.doProduct(prior, likelihood); | |
95 | |
96 // relativeSpeedPosterior.addToIndex(100, 1); | |
97 // relativeSpeedPosterior.addToIndex(40, 0.7); | |
98 relativeSpeedPosterior.addGaussianShape(100, 20, 1); | |
99 // relativeSpeedPosterior.addGaussianShape(10, 2, 0.5); | |
100 relativeSpeedPosterior.getMaximum(); | |
101 | |
102 } | |
103 | |
104 void BayesianArrayStructure::copyPriorToPosterior(){ | |
105 | |
106 for (int i = 0;i < prior.arraySize;i++){ | |
107 posterior.array[i] = prior.array[i]; | |
108 } | |
109 } | |
110 | |
111 void BayesianArrayStructure::resetArrays(){ | |
112 prior.zero(); | |
113 likelihood.zero(); | |
114 prior.addGaussianShape(0, 80, 1); | |
115 likelihood.addConstant(1); | |
116 posterior.zero(); | |
117 posterior.addGaussianShape(0, 60, 1); | |
118 setNewDistributionOffsets(0); | |
119 bestEstimate = 0; | |
120 // lastBestEstimateUpdateTime = ofGetElapsedTimeMillis(); | |
121 | |
122 } | |
123 | |
124 void BayesianArrayStructure::updateBestEstimate(){ | |
125 double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//lastBestEstimateUpdateTime; | |
126 | |
127 bestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate); | |
128 // | |
129 //lastBestEstimateUpdateTime = ofGetElapsedTimeMillis(); | |
130 } | |
131 | |
132 void BayesianArrayStructure::calculatePosterior(){ | |
133 posterior.doProduct(prior, likelihood); | |
134 posterior.renormalise(); | |
135 | |
136 /* | |
137 int i; | |
138 for (i = 0;i < prior.length;i++){ | |
139 // printf("priori [%i] is %f\n", i, prior[i]); | |
140 *(posterior+i) = *(prior+i); | |
141 // posterior[i] = likelihood[i] * prior[i]; | |
142 } | |
143 */ | |
144 | |
145 | |
146 } | |
147 | |
148 | |
149 | |
150 | |
151 void BayesianArrayStructure::setNewDistributionOffsets(const double& newOffset){ | |
152 prior.offset = newOffset; | |
153 likelihood.offset = newOffset; | |
154 // posterior.offset = newOffset; | |
155 } | |
156 | |
157 | |
158 void BayesianArrayStructure::crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference){ | |
159 //set the cutoff for offset of position first! XXX | |
160 | |
161 // printf("time difference %f, ", timeDifference); | |
162 | |
163 double timeDifferenceInPositionVectorUnits = timeDifference / prior.scalar; | |
164 | |
165 prior.zero();//kill prior | |
166 calculateNewPriorOffset(timeDifference);//set new prior offset here | |
167 | |
168 for (int i = 0;i < speed.arraySize;i++){ | |
169 // printf("[%i] %f\n", i, speed.array[i]); | |
170 //set speed | |
171 double speedValue = speed.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5 | |
172 | |
173 //so we have moved | |
174 int distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value | |
175 | |
176 if (speed.array[i] != 0){ | |
177 | |
178 // printf("speed [%i] gives %f moved %i\n", i, speedValue, distanceMoved); | |
179 | |
180 for (int postIndex = 0;postIndex < position.arraySize;postIndex++){ | |
181 //old posterior contributing to new prior | |
182 int newPriorIndex = postIndex + position.offset - prior.offset + distanceMoved; | |
183 if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){ | |
184 prior.addToIndex(newPriorIndex, position.array[postIndex]*speed.array[i]); | |
185 // printf("adding [%i] : %f\n", newPriorIndex, posterior.array[postIndex]*speed.array[i]); | |
186 } | |
187 | |
188 } | |
189 | |
190 }//if not zero | |
191 }//end speed | |
192 | |
193 prior.renormalise(); | |
194 | |
195 } | |
196 | |
197 void BayesianArrayStructure::calculateNewPriorOffset(const double& timeDifference){ | |
198 | |
199 double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.MAPestimate); | |
200 // printf("Maxspeed is %f\n", maxSpeed); | |
201 | |
202 double priorMax = posterior.getMaximum(); | |
203 double distanceTravelled = maxSpeed * (timeDifference / prior.scalar); | |
204 double newMaxLocation = posterior.MAPestimate + distanceTravelled; | |
205 // printf("MAP: %i, tim df %f, distance %f, new location %f\n", posterior.MAPestimate, timeDifference, distanceTravelled, newMaxLocation); | |
206 | |
207 } | |
208 | |
209 | |
210 void BayesianArrayStructure::decaySpeedDistribution(double timeDifference){ | |
211 | |
212 // commented for the moment | |
213 double relativeAmount = max(1.0, timeDifference/1000.); | |
214 // printf("decay %f around %i \n", timeDifference, relativeSpeedPosterior.MAPestimate); | |
215 relativeAmount *= speedDecayAmount; | |
216 relativeSpeedPosterior.renormalise(); | |
217 relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, relativeAmount); | |
218 | |
219 relativeSpeedPosterior.renormalise(); | |
220 double newMax = relativeSpeedPosterior.getMaximum(); | |
221 | |
222 //old code | |
223 // relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, 10); | |
224 //relativeSpeedPosterior.addConstant(1); | |
225 | |
226 /* | |
227 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior); | |
228 relativeSpeedLikelihood.zero(); | |
229 relativeSpeedLikelihood.addConstant(0.2); | |
230 relativeSpeedLikelihood.addGaussianShape(relativeSpeedPosterior.maximumValue, speedDecayWidth, relativeAmount); | |
231 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood); | |
232 relativeSpeedPosterior.renormalise(); | |
233 */ | |
234 | |
235 | |
236 | |
237 } | |
238 | |
239 void BayesianArrayStructure::updateTempoDistribution(const double& speedRatio, const double& matchFactor){ | |
240 //speedratio is speed of played relative to the recording | |
241 | |
242 double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio); | |
243 // printf("\nindex of likelihood would be %f\n", index); | |
244 if (index >= 0 && index < relativeSpeedPrior.length){ | |
245 //then we can do update | |
246 | |
247 //set new likelihood | |
248 relativeSpeedLikelihood.zero(); | |
249 relativeSpeedLikelihood.addConstant(0.02); | |
250 | |
251 relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5*matchFactor); | |
252 | |
253 | |
254 //copy posterior to prior | |
255 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior); | |
256 | |
257 //update | |
258 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood); | |
259 | |
260 //normalise | |
261 relativeSpeedPosterior.renormalise(); | |
262 | |
263 relativeSpeedPosterior.getMaximum(); | |
264 }//end if within range | |
265 | |
266 | |
267 } | |
268 | |
269 | |
270 void BayesianArrayStructure::setFlatTempoLikelihood(){ //set new likelihood | |
271 relativeSpeedLikelihood.zero(); | |
272 relativeSpeedLikelihood.addConstant(0.3); | |
273 } | |
274 | |
275 void BayesianArrayStructure::updateTempoLikelihood(const double& speedRatio, const double& matchFactor){ | |
276 | |
277 double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio); | |
278 | |
279 if (index >= 0 && index < relativeSpeedPrior.length){ | |
280 relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5);//*matchFactor); | |
281 } | |
282 } | |
283 | |
284 | |
285 void BayesianArrayStructure::calculateTempoUpdate(){ | |
286 //copy posterior to prior | |
287 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior); | |
288 | |
289 //update | |
290 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood); | |
291 | |
292 //normalise | |
293 relativeSpeedPosterior.renormalise(); | |
294 | |
295 relativeSpeedPosterior.getMaximum(); | |
296 | |
297 } | |
298 | |
299 | |
300 void BayesianArrayStructure::drawArrays(){ | |
301 | |
302 //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200); | |
303 //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200); | |
304 | |
305 int displaySize = prior.arraySize; | |
306 ofSetColor(255,0,0); | |
307 prior.drawVector(0, displaySize); | |
308 ofSetColor(0,255,0); | |
309 likelihood.drawVector(0, displaySize); | |
310 ofSetColor(0,0,255); | |
311 posterior.drawVector(0, displaySize); | |
312 ofSetColor(255,255,0); | |
313 relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize); | |
314 | |
315 // ofSetColor(255,255,255); | |
316 // tmpPrior.drawVector(0,300); | |
317 | |
318 } | |
319 | |
320 | |
321 void BayesianArrayStructure::drawTempoArrays(){ | |
322 ofSetColor(0,255,255); | |
323 relativeSpeedPrior.drawVector(0, relativeSpeedPrior.arraySize); | |
324 | |
325 ofSetColor(255,0,255); | |
326 relativeSpeedLikelihood.drawVector(0, relativeSpeedLikelihood.arraySize); | |
327 | |
328 ofSetColor(255,255,0); | |
329 relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize); | |
330 | |
331 ofSetColor(255,255, 255); | |
332 ofLine(screenWidth/2, 0, screenWidth/2, ofGetHeight());//middle of screen | |
333 | |
334 ofSetColor(0, 255, 0); | |
335 double fractionOfScreen = ((double)relativeSpeedPosterior.MAPestimate / relativeSpeedPosterior.length); | |
336 ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight()); | |
337 } | |
338 | |
339 | |
340 void BayesianArrayStructure::drawArraysRelativeToTimeframe(const double& startTimeMillis, const double& endTimeMillis){ | |
341 | |
342 screenWidth = ofGetWidth(); | |
343 | |
344 int startArrayIndex = 0; | |
345 | |
346 if (prior.getIndexInRealTerms(prior.arraySize-1) > startTimeMillis){ | |
347 //i.e. the array is on the page | |
348 | |
349 while (prior.getIndexInRealTerms(startArrayIndex) < startTimeMillis){ | |
350 startArrayIndex++; | |
351 } | |
352 int endArrayIndex = prior.arraySize-1; | |
353 //could find constraints here | |
354 if (prior.getIndexInRealTerms(prior.arraySize-1) > endTimeMillis) | |
355 endArrayIndex = (floor)((endTimeMillis - prior.offset)/prior.scalar); | |
356 | |
357 //so we need to figure where start and end array are on screen | |
358 int startScreenPosition, endScreenPosition; | |
359 double screenWidthMillis = endTimeMillis - startTimeMillis; | |
360 | |
361 startScreenPosition = (prior.getIndexInRealTerms(startArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis; | |
362 endScreenPosition = (double)(prior.getIndexInRealTerms(endArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis; | |
363 | |
364 ofSetColor(0,0,100); | |
365 string relativeString = " offset "+ofToString(prior.offset, 1);//starttimes("+ofToString(startTimeMillis)+", "+ofToString(endTimeMillis); | |
366 relativeString += ": index "+ofToString(startArrayIndex)+" , "+ofToString(endArrayIndex)+" ["; | |
367 // relativeString += ofToString(prior.getIndexInRealTerms(endArrayIndex), 3)+"] (sc-width:"+ofToString(screenWidthMillis, 1)+") "; | |
368 relativeString += " mapped to screen "+ofToString(startScreenPosition)+" , "+ofToString(endScreenPosition); | |
369 ofDrawBitmapString(relativeString, 100, 180); | |
370 | |
371 ofSetColor(0, 200, 0); | |
372 likelihood.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); | |
373 | |
374 ofSetColor(0,0,200); | |
375 prior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); | |
376 | |
377 ofSetColor(200, 0, 0); | |
378 posterior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); | |
379 | |
380 // ofSetColor(0, 200, 255); | |
381 // acceleration.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition); | |
382 | |
383 | |
384 } | |
385 | |
386 } |