andrew@33
|
1 /*
|
andrew@33
|
2 * BayesianArrayStructure.cpp
|
andrew@33
|
3 * midiCannamReader
|
andrew@33
|
4 *
|
andrew@33
|
5 * Created by Andrew on 17/07/2011.
|
andrew@33
|
6 * Copyright 2011 QMUL. All rights reserved.
|
andrew@33
|
7 *
|
andrew@33
|
8 */
|
andrew@33
|
9
|
andrew@33
|
10 //look at reset speed to one - what does this do? - get rid of?
|
andrew@33
|
11
|
andrew@33
|
12
|
andrew@33
|
13 #include "BayesianArrayStructure.h"
|
andrew@33
|
14
|
andrew@52
|
15 int priorColor = 0xEE00CC;//230,0,170
|
andrew@52
|
16 int posteriorColor = 0x444444;//000099;
|
andrew@52
|
17
|
andrew@33
|
18 BayesianArrayStructure::BayesianArrayStructure(){
|
andrew@46
|
19 printf("Bayesian structure: DeFault constructor called\n");
|
andrew@50
|
20 usingIntegratedTempoEstimate = false;// use max index
|
andrew@50
|
21
|
andrew@50
|
22 useConstantTempoDistribution = false;
|
andrew@33
|
23
|
andrew@33
|
24 relativeSpeedLikelihoodStdDev = 5.0;
|
andrew@33
|
25
|
andrew@33
|
26 prior.createVector(1);
|
andrew@52
|
27 likelihood.createVector(1);
|
andrew@33
|
28 posterior.createVector(1);
|
andrew@33
|
29
|
andrew@33
|
30
|
andrew@33
|
31 speedPriorValue = 1.0;
|
andrew@33
|
32 speedEstimate = speedPriorValue;
|
andrew@33
|
33
|
andrew@33
|
34 lastEventTime = 0;//ofGetElapsedTimeMillis();
|
andrew@33
|
35
|
andrew@46
|
36 //tmpBestEstimate = 0;
|
andrew@33
|
37 crossUpdateTimeThreshold = 60;
|
andrew@33
|
38 priorWidth = 50;
|
andrew@33
|
39
|
andrew@52
|
40 drawLikelihood = false;
|
andrew@52
|
41 drawPrior = true;
|
andrew@52
|
42 drawPosterior = true;
|
andrew@52
|
43
|
andrew@33
|
44 }
|
andrew@33
|
45
|
andrew@33
|
46 BayesianArrayStructure::BayesianArrayStructure(int length){
|
andrew@46
|
47 printf("BAYESIAN STURTUCRE CREATED LENGTH (EVER CALLED?????): %i\n", length);
|
andrew@33
|
48 //this constructor isnt called it seems
|
andrew@33
|
49 prior.createVector(length);
|
andrew@33
|
50 likelihood.createVector(length);
|
andrew@33
|
51 posterior.createVector(length);
|
andrew@33
|
52
|
andrew@33
|
53 lastEventTime = 0;
|
andrew@33
|
54
|
andrew@33
|
55
|
andrew@33
|
56 }
|
andrew@33
|
57
|
andrew@33
|
58
|
andrew@33
|
59
|
andrew@33
|
60 void BayesianArrayStructure::resetSize(int length){
|
andrew@33
|
61 printf("BAYESIAN STRUCTURE size is : %i\n", length);
|
andrew@33
|
62
|
andrew@33
|
63 prior.createVector(length);
|
andrew@33
|
64 likelihood.createVector(length);
|
andrew@33
|
65 posterior.createVector(length);
|
andrew@33
|
66
|
andrew@33
|
67 acceleration.createVector(length);
|
andrew@33
|
68
|
andrew@33
|
69 }
|
andrew@33
|
70
|
andrew@33
|
71
|
andrew@33
|
72
|
andrew@33
|
73 void BayesianArrayStructure::resetSpeedToOne(){
|
andrew@33
|
74 relativeSpeedPrior.zero();
|
andrew@33
|
75 relativeSpeedPosterior.zero();
|
andrew@33
|
76 relativeSpeedLikelihood.zero();
|
andrew@33
|
77
|
andrew@33
|
78
|
andrew@46
|
79 relativeSpeedPosterior.addGaussianShapeFromRealTime(1.0, 0.2, 0.8);
|
andrew@33
|
80 relativeSpeedPosterior.renormalise();
|
andrew@33
|
81 relativeSpeedPosterior.getMaximum();
|
andrew@33
|
82
|
andrew@33
|
83 setSpeedPrior(speedPriorValue);
|
andrew@33
|
84 speedEstimate = speedPriorValue;
|
andrew@33
|
85
|
andrew@46
|
86
|
andrew@46
|
87
|
andrew@33
|
88 prior.zero();
|
andrew@33
|
89 posterior.zero();
|
andrew@33
|
90
|
andrew@46
|
91 // posterior.addToIndex(0, 1);
|
andrew@46
|
92 // posterior.renormalise();
|
andrew@33
|
93
|
andrew@33
|
94
|
andrew@33
|
95 //acceleration.addGaussianShape(2000, 20, 0.8);
|
andrew@33
|
96
|
andrew@33
|
97 }
|
andrew@33
|
98
|
andrew@33
|
99 void BayesianArrayStructure::setSpeedPrior(double f){
|
andrew@33
|
100 speedPriorValue = f;
|
andrew@33
|
101 int index = relativeSpeedPosterior.getRealTermsAsIndex(speedPriorValue);
|
andrew@33
|
102 relativeSpeedPosterior.zero();
|
andrew@33
|
103 relativeSpeedPosterior.addGaussianShape(index, priorWidth, 0.8);
|
andrew@33
|
104 relativeSpeedPosterior.renormalise();
|
andrew@33
|
105 relativeSpeedPosterior.getMaximum();
|
andrew@33
|
106 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@33
|
107 printf("BAYES STRUCTU ' SPEED PRIOR %f . index %i\n", speedPriorValue, index);
|
andrew@33
|
108
|
andrew@33
|
109 }
|
andrew@33
|
110
|
andrew@33
|
111 void BayesianArrayStructure::resetSpeedSize(int length){
|
andrew@33
|
112 printf("BAYESIAN SPEED size is : %i\n", length);
|
andrew@33
|
113
|
andrew@33
|
114 relativeSpeedPrior.createVector(length);
|
andrew@33
|
115 relativeSpeedLikelihood.createVector(length);
|
andrew@33
|
116 relativeSpeedPosterior.createVector(length);
|
andrew@33
|
117 tmpPosteriorForStorage.createVector(length);
|
andrew@33
|
118
|
andrew@33
|
119
|
andrew@33
|
120
|
andrew@33
|
121 }
|
andrew@33
|
122
|
andrew@33
|
123 void BayesianArrayStructure::setRelativeSpeedScalar(double f){
|
andrew@33
|
124 relativeSpeedPrior.scalar = f;
|
andrew@33
|
125 relativeSpeedPosterior.scalar = f;
|
andrew@33
|
126 relativeSpeedLikelihood.scalar = f;
|
andrew@33
|
127 }
|
andrew@33
|
128
|
andrew@33
|
129
|
andrew@33
|
130 void BayesianArrayStructure::setPositionDistributionScalar(double f){
|
andrew@33
|
131 if (f > 0){
|
andrew@46
|
132 printf("Setting the scalar for time scale to be %f ms\n", f);
|
andrew@33
|
133 prior.scalar = f;
|
andrew@33
|
134 posterior.scalar = f;
|
andrew@33
|
135 likelihood.scalar = f;
|
andrew@33
|
136 }
|
andrew@33
|
137 }
|
andrew@33
|
138
|
andrew@33
|
139 void BayesianArrayStructure::simpleExample(){
|
andrew@33
|
140 relativeSpeedPosterior.getMaximum();
|
andrew@33
|
141 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@33
|
142 }
|
andrew@33
|
143
|
andrew@33
|
144 void BayesianArrayStructure::copyPriorToPosterior(){
|
andrew@33
|
145
|
andrew@33
|
146 for (int i = 0;i < prior.arraySize;i++){
|
andrew@33
|
147 posterior.array[i] = prior.array[i];
|
andrew@33
|
148 }
|
andrew@33
|
149 }
|
andrew@33
|
150
|
andrew@33
|
151 void BayesianArrayStructure::setStartPlaying(){
|
andrew@33
|
152
|
andrew@33
|
153 lastEventTime = 0;
|
andrew@33
|
154 bestEstimate = 0;
|
andrew@33
|
155 lastBestEstimateUpdateTime = 0;
|
andrew@33
|
156 if (*realTimeMode)
|
andrew@33
|
157 lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
|
andrew@33
|
158 //cannot just be zero - offline bug
|
andrew@34
|
159 //printf("start playing - best estimate %f\n", lastBestEstimateUpdateTime);
|
andrew@33
|
160
|
andrew@33
|
161 resetArrays();
|
andrew@33
|
162 }
|
andrew@33
|
163
|
andrew@33
|
164 void BayesianArrayStructure::resetArrays(){
|
andrew@33
|
165 //called when we start playing
|
andrew@33
|
166
|
andrew@33
|
167 prior.zero();
|
andrew@33
|
168 likelihood.zero();
|
andrew@33
|
169 posterior.zero();
|
andrew@33
|
170
|
andrew@33
|
171 updateCounter = 0;
|
andrew@33
|
172
|
andrew@33
|
173 posterior.offset = -1000;
|
andrew@46
|
174 setNewDistributionOffsets(posterior.offset);
|
andrew@33
|
175
|
andrew@33
|
176 int zeroIndex = posterior.getRealTermsAsIndex(0);
|
andrew@46
|
177 posterior.addGaussianShapeFromRealTime(0, 500, 1);
|
andrew@33
|
178 // posterior.addToIndex(0, 1);
|
andrew@33
|
179 likelihood.addConstant(1);
|
andrew@33
|
180
|
andrew@33
|
181 updateCounter = 0;
|
andrew@46
|
182 posterior.getMaximum();
|
andrew@46
|
183 bestEstimate = posterior.getRealTermsAsIndex(0);
|
andrew@33
|
184
|
andrew@50
|
185
|
andrew@46
|
186 printf("bayes reset arrays - best estimate time %f\n", lastBestEstimateUpdateTime);
|
andrew@33
|
187
|
andrew@33
|
188 setSpeedPrior(speedPriorValue);
|
andrew@46
|
189 //posterior.printArray();
|
andrew@33
|
190 }
|
andrew@33
|
191
|
andrew@33
|
192
|
andrew@33
|
193 void BayesianArrayStructure::zeroArrays(){
|
andrew@33
|
194 prior.zero();
|
andrew@33
|
195 likelihood.zero();
|
andrew@33
|
196 posterior.zero();
|
andrew@33
|
197
|
andrew@33
|
198 relativeSpeedPrior.zero();
|
andrew@33
|
199 relativeSpeedPosterior.zero();
|
andrew@33
|
200 relativeSpeedLikelihood.zero();
|
andrew@33
|
201
|
andrew@33
|
202 }
|
andrew@33
|
203
|
andrew@46
|
204 /*
|
andrew@33
|
205 void BayesianArrayStructure::updateTmpBestEstimate(const double& timeDifference){
|
andrew@33
|
206 //input is the time since the start of playing
|
andrew@33
|
207 // double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//lastBestEstimateUpdateTime;
|
andrew@34
|
208 double timeDiff = timeDifference;
|
andrew@34
|
209 if (*realTimeMode)
|
andrew@34
|
210 timeDiff = ofGetElapsedTimeMillis() - lastBestEstimateUpdateTime;
|
andrew@34
|
211
|
andrew@34
|
212 double tmp = relativeSpeedPosterior.getIntegratedEstimate();
|
andrew@46
|
213 tmpBestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*relativeSpeedPosterior.getIndexInRealTerms(getSpeedEstimateIndex());
|
andrew@33
|
214 //
|
andrew@34
|
215 //printf("tmp best %f and best %f time diff %f posterior MAP %f at speed %f\n", 0Estimate, bestEstimate, timeDifference, posterior.getIndexInRealTerms(posterior.MAPestimate), relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate));
|
andrew@33
|
216 //lastBestEstimateUpdateTime = ofGetElapsedTimeMillis();
|
andrew@33
|
217 }
|
andrew@46
|
218 */
|
andrew@33
|
219
|
andrew@33
|
220 void BayesianArrayStructure::updateBestEstimate(const double& timeDifference){
|
andrew@33
|
221 // double timeDiff = ofGetElapsedTimeMillis() - lastEventTime;//
|
andrew@33
|
222
|
andrew@33
|
223 double timeDiff = timeDifference;
|
andrew@33
|
224
|
andrew@33
|
225 //Using timedifferencfe here will make it go wrong. Is time since beginning of playing
|
andrew@33
|
226
|
andrew@33
|
227 if (*realTimeMode)
|
andrew@33
|
228 timeDiff = ofGetElapsedTimeMillis() - lastBestEstimateUpdateTime;
|
andrew@33
|
229
|
andrew@34
|
230 //lastbest is time we started playing
|
andrew@34
|
231
|
andrew@46
|
232 speedEstimateIndex = getSpeedEstimateIndex();
|
andrew@46
|
233 /*
|
andrew@33
|
234 if (usingIntegratedTempoEstimate)
|
andrew@34
|
235 speedEstimateIndex = relativeSpeedPosterior.getIntegratedEstimate();
|
andrew@33
|
236 else
|
andrew@34
|
237 speedEstimateIndex = relativeSpeedPosterior.MAPestimate;
|
andrew@46
|
238 */
|
andrew@34
|
239 speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(speedEstimateIndex);
|
andrew@33
|
240 bestEstimate = posterior.getIndexInRealTerms(posterior.MAPestimate) + timeDiff*speedEstimate;
|
andrew@33
|
241
|
andrew@33
|
242 }
|
andrew@33
|
243
|
andrew@33
|
244 void BayesianArrayStructure::calculatePosterior(){
|
andrew@33
|
245 //posterior.doProduct(prior, likelihood);
|
andrew@33
|
246
|
andrew@33
|
247 int i;
|
andrew@33
|
248 for (i = 0;i < posterior.length;i++){
|
andrew@33
|
249 posterior.array[i] = likelihood.array[i] * prior.array[i];
|
andrew@33
|
250 }
|
andrew@33
|
251
|
andrew@33
|
252
|
andrew@33
|
253 posterior.renormalise();
|
andrew@33
|
254
|
andrew@33
|
255
|
andrew@33
|
256
|
andrew@33
|
257
|
andrew@33
|
258 }
|
andrew@33
|
259
|
andrew@33
|
260
|
andrew@33
|
261
|
andrew@33
|
262
|
andrew@33
|
263 void BayesianArrayStructure::setNewDistributionOffsets(const double& newOffset){
|
andrew@33
|
264 prior.offset = newOffset;
|
andrew@33
|
265 likelihood.offset = newOffset;
|
andrew@33
|
266 //posterior.offset = newOffset;
|
andrew@33
|
267 }
|
andrew@33
|
268
|
andrew@33
|
269
|
andrew@33
|
270 void BayesianArrayStructure::crossUpdateArrays(DynamicVector& position, DynamicVector& speed, double timeDifference){
|
andrew@33
|
271 //set the cutoff for offset of position first! XXX
|
andrew@46
|
272
|
andrew@33
|
273
|
andrew@33
|
274 double timeDifferenceInPositionVectorUnits = timeDifference / prior.scalar;
|
andrew@47
|
275 // printf("CCUPDATE time difference %f in units %f\n", timeDifference, timeDifferenceInPositionVectorUnits);
|
andrew@33
|
276
|
andrew@33
|
277 prior.zero();//kill prior
|
andrew@46
|
278 //calculateNewPriorOffset(timeDifference);//doesnt do anything
|
andrew@33
|
279
|
andrew@46
|
280 if (timeDifferenceInPositionVectorUnits > (crossUpdateTimeThreshold/prior.scalar))
|
andrew@33
|
281 complexCrossUpdate(timeDifferenceInPositionVectorUnits);
|
andrew@33
|
282 else
|
andrew@33
|
283 translateByMaximumSpeed(timeDifferenceInPositionVectorUnits);
|
andrew@33
|
284
|
andrew@33
|
285
|
andrew@33
|
286 updateCounter++;
|
andrew@33
|
287 prior.renormalise();
|
andrew@33
|
288
|
andrew@33
|
289 }
|
andrew@33
|
290
|
andrew@33
|
291 void BayesianArrayStructure::complexCrossUpdate(const double& timeDifferenceInPositionVectorUnits){
|
andrew@46
|
292 //distance moved is in vector units - but offsets are in millis. need to find first index
|
andrew@46
|
293
|
andrew@33
|
294 int distanceMoved, newPriorIndex;
|
andrew@46
|
295 // printf("post off %f prior off %f\n", posterior.offset, prior.offset);
|
andrew@33
|
296
|
andrew@33
|
297 double speedValue = relativeSpeedPosterior.offset;
|
andrew@33
|
298
|
andrew@33
|
299 for (int i = 0;i < relativeSpeedPosterior.arraySize;i++){
|
andrew@33
|
300
|
andrew@33
|
301 // double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
|
andrew@33
|
302
|
andrew@33
|
303 //so we have moved
|
andrew@33
|
304 distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
|
andrew@33
|
305
|
andrew@33
|
306 if (relativeSpeedPosterior.array[i] != 0){
|
andrew@33
|
307 double speedContribution = relativeSpeedPosterior.array[i];
|
andrew@33
|
308
|
andrew@46
|
309 newPriorIndex = (int)(posterior.millisToVectorUnits(posterior.offset - prior.offset)) + distanceMoved;
|
andrew@46
|
310
|
andrew@46
|
311 // printf("speed [%i] gives %f moved %i in %f units :: %f contributed new ptior %i\n",
|
andrew@46
|
312 // i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits, speedContribution, newPriorIndex);
|
andrew@46
|
313
|
andrew@46
|
314
|
andrew@33
|
315
|
andrew@33
|
316 for (int postIndex = 0;postIndex < posterior.arraySize;postIndex++){
|
andrew@33
|
317 //old posterior contributing to new prior
|
andrew@33
|
318 // newPriorIndex = postIndex + posterior.offset - prior.offset + distanceMoved;
|
andrew@33
|
319
|
andrew@33
|
320 if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
|
andrew@33
|
321 prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
|
andrew@33
|
322 }
|
andrew@33
|
323
|
andrew@33
|
324 newPriorIndex++;//optimised code - the commented line above explains how this works
|
andrew@33
|
325 }//end for
|
andrew@33
|
326
|
andrew@33
|
327
|
andrew@33
|
328 }//if not zero
|
andrew@33
|
329 speedValue += relativeSpeedPosterior.scalar;
|
andrew@33
|
330 //optimised line
|
andrew@33
|
331 //as we wanted:
|
andrew@33
|
332 // double speedValue = relativeSpeedPosterior.getIndexInRealTerms(i);//so for scalar 0.01, 50 -> speed value of 0.5
|
andrew@33
|
333 }//end speed
|
andrew@33
|
334 }
|
andrew@33
|
335
|
andrew@46
|
336 double BayesianArrayStructure::getSpeedEstimateIndex(){
|
andrew@46
|
337 if (usingIntegratedTempoEstimate)
|
andrew@46
|
338 return relativeSpeedPosterior.getIntegratedEstimate();
|
andrew@46
|
339 else
|
andrew@46
|
340 return relativeSpeedPosterior.getMAPestimate();
|
andrew@46
|
341 }
|
andrew@33
|
342
|
andrew@33
|
343
|
andrew@33
|
344 void BayesianArrayStructure::translateByMaximumSpeed(const double& timeDifferenceInPositionVectorUnits){
|
andrew@33
|
345
|
andrew@33
|
346 int distanceMoved, newPriorIndex;
|
andrew@33
|
347
|
andrew@46
|
348 double speedValue = relativeSpeedPosterior.getIndexInRealTerms(getSpeedEstimateIndex());
|
andrew@33
|
349 //so for scalar 0.01, 50 -> speed value of 0.5
|
andrew@46
|
350 double speedContribution = relativeSpeedPosterior.array[(int)getSpeedEstimateIndex()];//relativeSpeedPosterior.integratedEstimate
|
andrew@33
|
351 //so we have moved
|
andrew@33
|
352 distanceMoved = round(timeDifferenceInPositionVectorUnits * speedValue);//round the value
|
andrew@33
|
353 // printf("speed [%i] gives %f moved %i in %f units \n", i, speedValue, distanceMoved, timeDifferenceInPositionVectorUnits);
|
andrew@33
|
354
|
andrew@33
|
355 for (int postIndex = 0;postIndex < posterior.arraySize;postIndex++){
|
andrew@33
|
356 //old posterior contributing to new prior
|
andrew@46
|
357 newPriorIndex = (int)(posterior.millisToVectorUnits(posterior.offset - prior.offset)) + postIndex + distanceMoved;
|
andrew@33
|
358 if (newPriorIndex >= 0 && newPriorIndex < prior.arraySize){
|
andrew@33
|
359 prior.addToIndex(newPriorIndex, posterior.array[postIndex]*speedContribution);
|
andrew@33
|
360 }
|
andrew@33
|
361
|
andrew@33
|
362 }
|
andrew@33
|
363
|
andrew@33
|
364 }
|
andrew@33
|
365
|
andrew@33
|
366 void BayesianArrayStructure::addGaussianNoiseToSpeedPosterior(const double& std_dev){
|
andrew@33
|
367 tmpPosteriorForStorage.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@33
|
368
|
andrew@33
|
369 for (int i = 0;i < relativeSpeedPosterior.length;i++){
|
andrew@33
|
370 tmpPosteriorForStorage.addGaussianShape(i, std_dev, relativeSpeedPosterior.array[i]);
|
andrew@33
|
371 }
|
andrew@33
|
372
|
andrew@33
|
373 tmpPosteriorForStorage.renormalise();
|
andrew@33
|
374
|
andrew@33
|
375 relativeSpeedPosterior.copyFromDynamicVector(tmpPosteriorForStorage);
|
andrew@33
|
376 }
|
andrew@33
|
377
|
andrew@33
|
378
|
andrew@33
|
379 void BayesianArrayStructure::addTriangularNoiseToSpeedPosterior(const double& std_dev){
|
andrew@33
|
380 tmpPosteriorForStorage.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@33
|
381
|
andrew@33
|
382 for (int i = 0;i < relativeSpeedPosterior.length;i++){
|
andrew@33
|
383 //adding a linear amount depending on distance
|
andrew@33
|
384 tmpPosteriorForStorage.addTriangularShape(i, std_dev*2.0, relativeSpeedPosterior.array[i]);
|
andrew@33
|
385 }
|
andrew@33
|
386
|
andrew@33
|
387 tmpPosteriorForStorage.renormalise();
|
andrew@33
|
388
|
andrew@33
|
389 relativeSpeedPosterior.copyFromDynamicVector(tmpPosteriorForStorage);
|
andrew@33
|
390 }
|
andrew@46
|
391 /*
|
andrew@33
|
392 void BayesianArrayStructure::calculateNewPriorOffset(const double& timeDifference){
|
andrew@33
|
393
|
andrew@33
|
394 double maxSpeed = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
|
andrew@33
|
395 // printf("Maxspeed is %f\n", maxSpeed);
|
andrew@33
|
396
|
andrew@33
|
397 double priorMax = posterior.getMaximum();
|
andrew@33
|
398 double distanceTravelled = maxSpeed * (timeDifference / prior.scalar);
|
andrew@33
|
399 double newMaxLocation = posterior.MAPestimate + distanceTravelled;
|
andrew@33
|
400 // printf("MAP: %i, tim df %f, distance %f, new location %f\n", posterior.MAPestimate, timeDifference, distanceTravelled, newMaxLocation);
|
andrew@33
|
401
|
andrew@33
|
402 }
|
andrew@46
|
403 */
|
andrew@33
|
404
|
andrew@33
|
405 void BayesianArrayStructure::decaySpeedDistribution(double timeDifference){
|
andrew@33
|
406
|
andrew@33
|
407 // commented for the moment
|
andrew@33
|
408 double relativeAmount = max(1.0, timeDifference/1000.);
|
andrew@33
|
409 // printf("decay %f around %i \n", timeDifference, relativeSpeedPosterior.MAPestimate);
|
andrew@33
|
410 relativeAmount *= speedDecayAmount;
|
andrew@33
|
411 relativeSpeedPosterior.renormalise();
|
andrew@33
|
412 relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, relativeAmount);
|
andrew@33
|
413
|
andrew@33
|
414 relativeSpeedPosterior.renormalise();
|
andrew@33
|
415 double newMax = relativeSpeedPosterior.getMaximum();
|
andrew@33
|
416
|
andrew@33
|
417 //old code
|
andrew@33
|
418 // relativeSpeedPosterior.addGaussianShape(relativeSpeedPosterior.MAPestimate, speedDecayWidth, 10);
|
andrew@33
|
419 //relativeSpeedPosterior.addConstant(1);
|
andrew@33
|
420
|
andrew@33
|
421 /*
|
andrew@33
|
422 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@33
|
423 relativeSpeedLikelihood.zero();
|
andrew@33
|
424 relativeSpeedLikelihood.addConstant(0.2);
|
andrew@33
|
425 relativeSpeedLikelihood.addGaussianShape(relativeSpeedPosterior.maximumValue, speedDecayWidth, relativeAmount);
|
andrew@33
|
426 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
|
andrew@33
|
427 relativeSpeedPosterior.renormalise();
|
andrew@33
|
428 */
|
andrew@33
|
429
|
andrew@33
|
430
|
andrew@33
|
431
|
andrew@33
|
432 }
|
andrew@33
|
433
|
andrew@33
|
434 void BayesianArrayStructure::setLikelihoodToConstant(){
|
andrew@33
|
435 //set new likelihood
|
andrew@33
|
436 relativeSpeedLikelihood.zero();
|
andrew@33
|
437 relativeSpeedLikelihood.addConstant(speedLikelihoodNoise);
|
andrew@33
|
438 }
|
andrew@33
|
439
|
andrew@33
|
440
|
andrew@33
|
441 void BayesianArrayStructure::updateTempoLikelihood(const double& speedRatio, const double& matchFactor){
|
andrew@33
|
442
|
andrew@33
|
443 //speedratio is speed of played relative to the recording
|
andrew@33
|
444
|
andrew@33
|
445 double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
|
andrew@33
|
446 // printf("index of likelihood would be %f for ratio %f\n", index, speedRatio);
|
andrew@33
|
447 if (index >= 0 && index < relativeSpeedPrior.length){
|
andrew@33
|
448 relativeSpeedLikelihood.addGaussianShape(index , relativeSpeedLikelihoodStdDev, matchFactor);
|
andrew@33
|
449 }
|
andrew@33
|
450 }
|
andrew@33
|
451
|
andrew@33
|
452
|
andrew@33
|
453
|
andrew@33
|
454 void BayesianArrayStructure::updateTempoDistribution(){
|
andrew@33
|
455
|
andrew@33
|
456 //copy posterior to prior
|
andrew@33
|
457 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@33
|
458
|
andrew@33
|
459 //update
|
andrew@33
|
460 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
|
andrew@33
|
461
|
andrew@33
|
462 //normalise
|
andrew@33
|
463 relativeSpeedPosterior.renormalise();
|
andrew@33
|
464
|
andrew@33
|
465 relativeSpeedPosterior.getMaximum();
|
andrew@33
|
466
|
andrew@34
|
467 //relativeSpeedPosterior.updateIntegratedEstimate(); - could be swayed when off to side
|
andrew@34
|
468 //so now limited to where there is room sround the MAP estimate
|
andrew@33
|
469 relativeSpeedPosterior.updateLimitedIntegratedEstimate();
|
andrew@33
|
470
|
andrew@33
|
471 speedEstimate = relativeSpeedPosterior.getIndexInRealTerms(relativeSpeedPosterior.integratedEstimate);
|
andrew@50
|
472
|
andrew@50
|
473 if (useConstantTempoDistribution){
|
andrew@50
|
474 //tmp try constant tempo
|
andrew@50
|
475 relativeSpeedPosterior.zero();
|
andrew@50
|
476 relativeSpeedPosterior.addConstant(1);
|
andrew@50
|
477 relativeSpeedPosterior.renormalise();
|
andrew@50
|
478 }
|
andrew@33
|
479 }
|
andrew@33
|
480
|
andrew@33
|
481
|
andrew@33
|
482 void BayesianArrayStructure::calculateTempoUpdate(){
|
andrew@33
|
483 //copy posterior to prior
|
andrew@33
|
484 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@33
|
485
|
andrew@33
|
486 //update
|
andrew@33
|
487 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
|
andrew@33
|
488
|
andrew@33
|
489 //normalise
|
andrew@33
|
490 relativeSpeedPosterior.renormalise();
|
andrew@33
|
491
|
andrew@33
|
492 relativeSpeedPosterior.getMaximum();
|
andrew@33
|
493
|
andrew@33
|
494 }
|
andrew@33
|
495
|
andrew@33
|
496
|
andrew@33
|
497 void BayesianArrayStructure::drawArrays(){
|
andrew@33
|
498
|
andrew@33
|
499 //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
|
andrew@33
|
500 //bayesArray.drawFloatArray(&bayesArray.prior[0], 0, 200);
|
andrew@33
|
501
|
andrew@33
|
502 int displaySize = prior.arraySize;
|
andrew@33
|
503 ofSetColor(0,0,255);
|
andrew@33
|
504 prior.drawVector(0, displaySize);
|
andrew@33
|
505 ofSetColor(0,255,0);
|
andrew@33
|
506 likelihood.drawVector(0, displaySize);
|
andrew@33
|
507 ofSetColor(255,0,255);
|
andrew@33
|
508 posterior.drawVector(0, displaySize);
|
andrew@33
|
509
|
andrew@33
|
510
|
andrew@33
|
511
|
andrew@33
|
512 }
|
andrew@33
|
513
|
andrew@33
|
514
|
andrew@33
|
515 void BayesianArrayStructure::drawTempoArrays(){
|
andrew@33
|
516 ofSetColor(0,0,255);
|
andrew@33
|
517 // relativeSpeedPrior.drawVector(0, relativeSpeedPrior.arraySize);
|
andrew@33
|
518
|
andrew@33
|
519 ofSetColor(0,150,255);
|
andrew@33
|
520 relativeSpeedLikelihood.drawVector(0, relativeSpeedLikelihood.arraySize);
|
andrew@33
|
521
|
andrew@33
|
522 // relativeSpeedLikelihood.drawConstrainedVector(0, 199, 0, 1000);// relativeSpeedLikelihood.arraySize);
|
andrew@33
|
523 ofSetColor(255,0,0);
|
andrew@33
|
524 relativeSpeedPosterior.drawVector(0, relativeSpeedPosterior.arraySize);
|
andrew@33
|
525
|
andrew@33
|
526 // ofSetColor(0,0,255);
|
andrew@33
|
527 // tmpPosteriorForStorage.drawVector(0, tmpPosteriorForStorage.arraySize);
|
andrew@33
|
528
|
andrew@33
|
529 ofSetColor(255,255, 255);
|
andrew@33
|
530 ofLine(screenWidth/2, 0, screenWidth/2, ofGetHeight());//middle of screen
|
andrew@33
|
531
|
andrew@33
|
532 ofSetColor(25, 0, 250);
|
andrew@33
|
533 double fractionOfScreen = ((double)relativeSpeedPosterior.integratedEstimate / relativeSpeedPosterior.length);
|
andrew@33
|
534 ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
|
andrew@33
|
535
|
andrew@33
|
536 ofSetColor(255, 0, 20);
|
andrew@33
|
537 fractionOfScreen = ((double)relativeSpeedPosterior.MAPestimate / relativeSpeedPosterior.length);
|
andrew@33
|
538 ofLine(screenWidth * fractionOfScreen, 0, screenWidth * fractionOfScreen, ofGetHeight());
|
andrew@33
|
539
|
andrew@33
|
540
|
andrew@33
|
541 }
|
andrew@33
|
542
|
andrew@33
|
543
|
andrew@33
|
544 void BayesianArrayStructure::drawArraysRelativeToTimeframe(const double& startTimeMillis, const double& endTimeMillis){
|
andrew@33
|
545
|
andrew@33
|
546 screenWidth = ofGetWidth();
|
andrew@33
|
547
|
andrew@33
|
548 int startArrayIndex = 0;
|
andrew@33
|
549
|
andrew@33
|
550 if (prior.getIndexInRealTerms(prior.arraySize-1) > startTimeMillis){
|
andrew@33
|
551 //i.e. the array is on the page
|
andrew@33
|
552
|
andrew@33
|
553 while (prior.getIndexInRealTerms(startArrayIndex) < startTimeMillis){
|
andrew@33
|
554 startArrayIndex++;
|
andrew@33
|
555 }
|
andrew@33
|
556 int endArrayIndex = prior.arraySize-1;
|
andrew@33
|
557 //could find constraints here
|
andrew@33
|
558 if (prior.getIndexInRealTerms(prior.arraySize-1) > endTimeMillis)
|
andrew@33
|
559 endArrayIndex = (floor)((endTimeMillis - prior.offset)/prior.scalar);
|
andrew@33
|
560
|
andrew@33
|
561 //so we need to figure where start and end array are on screen
|
andrew@33
|
562 int startScreenPosition, endScreenPosition;
|
andrew@33
|
563 double screenWidthMillis = endTimeMillis - startTimeMillis;
|
andrew@33
|
564
|
andrew@33
|
565 startScreenPosition = (prior.getIndexInRealTerms(startArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
|
andrew@33
|
566 endScreenPosition = (double)(prior.getIndexInRealTerms(endArrayIndex) - startTimeMillis)*screenWidth/screenWidthMillis;
|
andrew@33
|
567
|
andrew@33
|
568 ofSetColor(0,0,100);
|
andrew@33
|
569 string relativeString = " offset "+ofToString(prior.offset, 1);//starttimes("+ofToString(startTimeMillis)+", "+ofToString(endTimeMillis);
|
andrew@33
|
570 relativeString += ": index "+ofToString(startArrayIndex)+" , "+ofToString(endArrayIndex)+" [";
|
andrew@33
|
571 // relativeString += ofToString(prior.getIndexInRealTerms(endArrayIndex), 3)+"] (sc-width:"+ofToString(screenWidthMillis, 1)+") ";
|
andrew@33
|
572 relativeString += " mapped to screen "+ofToString(startScreenPosition)+" , "+ofToString(endScreenPosition);
|
andrew@33
|
573 // ofDrawBitmapString(relativeString, 100, 180);
|
andrew@33
|
574
|
andrew@33
|
575
|
andrew@52
|
576 if (drawLikelihood){
|
andrew@52
|
577 ofSetColor(100,100,100);//255, 255, 0);
|
andrew@52
|
578 likelihood.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
|
andrew@52
|
579 }
|
andrew@33
|
580
|
andrew@52
|
581 if (drawPrior){
|
andrew@52
|
582 ofSetHexColor(priorColor);//00,200);
|
andrew@52
|
583 prior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
|
andrew@52
|
584 }
|
andrew@33
|
585
|
andrew@52
|
586 if (drawPosterior){
|
andrew@52
|
587 ofSetHexColor(posteriorColor);
|
andrew@52
|
588 // ofSetColor(200, 0, 0);
|
andrew@52
|
589 posterior.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
|
andrew@52
|
590 }
|
andrew@33
|
591
|
andrew@33
|
592 // ofSetColor(0, 200, 255);
|
andrew@33
|
593 // acceleration.drawConstrainedVector(startArrayIndex, endArrayIndex, startScreenPosition, endScreenPosition);
|
andrew@33
|
594
|
andrew@33
|
595
|
andrew@33
|
596 }
|
andrew@33
|
597
|
andrew@33
|
598 }
|
andrew@33
|
599
|
andrew@33
|
600
|
andrew@33
|
601 /*
|
andrew@33
|
602
|
andrew@33
|
603 void BayesianArrayStructure::updateTempoDistribution(const double& speedRatio, const double& matchFactor){
|
andrew@33
|
604 //speedratio is speed of played relative to the recording
|
andrew@33
|
605
|
andrew@33
|
606 double index = relativeSpeedLikelihood.getRealTermsAsIndex(speedRatio);
|
andrew@33
|
607 // printf("\nindex of likelihood would be %f\n", index);
|
andrew@33
|
608 if (index >= 0 && index < relativeSpeedPrior.length){
|
andrew@33
|
609 //then we can do update
|
andrew@33
|
610
|
andrew@33
|
611 //set new likelihood
|
andrew@33
|
612 relativeSpeedLikelihood.zero();
|
andrew@33
|
613 relativeSpeedLikelihood.addConstant(speedLikelihoodNoise);
|
andrew@33
|
614
|
andrew@33
|
615 relativeSpeedLikelihood.addGaussianShape(index , 5, 0.5*matchFactor);
|
andrew@33
|
616
|
andrew@33
|
617
|
andrew@33
|
618 //copy posterior to prior
|
andrew@33
|
619 relativeSpeedPrior.copyFromDynamicVector(relativeSpeedPosterior);
|
andrew@33
|
620
|
andrew@33
|
621 //update
|
andrew@33
|
622 relativeSpeedPosterior.doProduct(relativeSpeedPrior, relativeSpeedLikelihood);
|
andrew@33
|
623
|
andrew@33
|
624 //normalise
|
andrew@33
|
625 relativeSpeedPosterior.renormalise();
|
andrew@33
|
626
|
andrew@33
|
627 relativeSpeedPosterior.getMaximum();
|
andrew@33
|
628 }//end if within range
|
andrew@33
|
629
|
andrew@33
|
630
|
andrew@33
|
631 }
|
andrew@33
|
632
|
andrew@33
|
633 */ |