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