andrew@33
|
1 /*
|
andrew@33
|
2 * DynamicVector.cpp
|
andrew@33
|
3 * midiCannamReader
|
andrew@33
|
4 *
|
andrew@33
|
5 * Created by Andrew on 18/07/2011.
|
andrew@33
|
6 * Copyright 2011 QMUL. All rights reserved.
|
andrew@33
|
7 *
|
andrew@33
|
8 */
|
andrew@33
|
9
|
andrew@33
|
10
|
andrew@33
|
11 #include "DynamicVector.h"
|
andrew@33
|
12
|
andrew@33
|
13 DynamicVector::DynamicVector(){
|
andrew@33
|
14 length = 0;
|
andrew@33
|
15 arraySize = 0;
|
andrew@33
|
16 maximumValue = 0;
|
andrew@33
|
17 MAPestimate = 0;
|
andrew@33
|
18 offset = 0;
|
andrew@33
|
19 scalar = 1;
|
andrew@33
|
20 integratedEstimate = length/2;
|
andrew@33
|
21
|
andrew@33
|
22 gaussianLookupMean = (double) GAUSSIAN_LOOKUP_LENGTH/2;
|
andrew@33
|
23 gaussianLookupStdDev = (double)(GAUSSIAN_LOOKUP_LENGTH/16);
|
andrew@33
|
24 double factor = 1.0;//(1.0 / (gaussianLookupStdDev*sqrt(2*PI)) );//1.0;//-1.0/(2*PI*sqrt(gaussianLookupStdDev));
|
andrew@33
|
25 for (int i = 0;i < GAUSSIAN_LOOKUP_LENGTH;i++){
|
andrew@33
|
26 gaussianLookupTable[i] = factor*exp(-1.0*(i-gaussianLookupMean)*(i-gaussianLookupMean)/(2.0*gaussianLookupStdDev*gaussianLookupStdDev));
|
andrew@33
|
27 }
|
andrew@33
|
28
|
andrew@33
|
29 }
|
andrew@33
|
30
|
andrew@33
|
31 void DynamicVector::copyFromDynamicVector(const DynamicVector& dynamicVec){
|
andrew@33
|
32 if (dynamicVec.length == length){
|
andrew@44
|
33 offset = dynamicVec.offset;
|
andrew@33
|
34 for (int i = 0;i < length;i++)
|
andrew@33
|
35 array[i] = dynamicVec.array[i];
|
andrew@33
|
36 }
|
andrew@33
|
37 else{
|
andrew@33
|
38 printf("CANNOT COPY VECTORS OF NON SAME LENGTH!!\n");
|
andrew@33
|
39 }
|
andrew@33
|
40 }
|
andrew@33
|
41
|
andrew@33
|
42 void DynamicVector::createVector(int len){
|
andrew@33
|
43 array.clear();
|
andrew@33
|
44 for (int i = 0; i < len;i++){
|
andrew@33
|
45 array.push_back(0);
|
andrew@33
|
46 }
|
andrew@33
|
47 length = len;
|
andrew@33
|
48 arraySize = array.size();
|
andrew@33
|
49 integratedEstimate = length/2;
|
andrew@33
|
50 }
|
andrew@33
|
51
|
andrew@33
|
52
|
andrew@33
|
53 double DynamicVector::getMaximum(){
|
andrew@33
|
54 int i;
|
andrew@33
|
55 double max = 0;
|
andrew@33
|
56 for (i=0;i < length;i++){
|
andrew@33
|
57 if (array[i] > max){
|
andrew@33
|
58 max = array[i];
|
andrew@33
|
59 MAPestimate = i;
|
andrew@33
|
60 }
|
andrew@33
|
61 }
|
andrew@33
|
62 maximumValue = max;
|
andrew@33
|
63 return max;
|
andrew@33
|
64 }
|
andrew@33
|
65
|
andrew@33
|
66 double DynamicVector::getIntegratedEstimate(){
|
andrew@33
|
67 //returns the index of the integrated average - where the probability distribution is centred
|
andrew@33
|
68 integratedEstimate = 0;
|
andrew@33
|
69 double integratedTotal = 0;
|
andrew@33
|
70 for (int i = 0;i < length;i++){
|
andrew@33
|
71 integratedEstimate += array[i]*i;
|
andrew@33
|
72 integratedTotal += array[i];
|
andrew@33
|
73 }
|
andrew@33
|
74 if (integratedTotal > 0){
|
andrew@33
|
75 integratedEstimate /= integratedTotal;
|
andrew@33
|
76 }
|
andrew@33
|
77 return integratedEstimate;
|
andrew@33
|
78 }
|
andrew@33
|
79
|
andrew@33
|
80 void DynamicVector::updateIntegratedEstimate(){
|
andrew@33
|
81 //returns the index of the integrated average - where the probability distribution is centred
|
andrew@33
|
82 integratedEstimate = 0;
|
andrew@33
|
83 double integratedTotal = 0;
|
andrew@33
|
84 for (int i = 0;i < length;i++){
|
andrew@33
|
85 integratedEstimate += array[i]*i;
|
andrew@33
|
86 integratedTotal += array[i];
|
andrew@33
|
87 }
|
andrew@33
|
88 if (integratedTotal > 0){
|
andrew@33
|
89 integratedEstimate /= integratedTotal;
|
andrew@33
|
90 }
|
andrew@33
|
91
|
andrew@33
|
92 }
|
andrew@33
|
93
|
andrew@33
|
94 void DynamicVector::updateLimitedIntegratedEstimate(){
|
andrew@33
|
95 //returns the index of the integrated average - where the probability distribution is centred
|
andrew@33
|
96 //but limited round the MAP estimate
|
andrew@33
|
97 double tmp = getMaximum();
|
andrew@33
|
98 int limit = min(MAPestimate, length - MAPestimate);
|
andrew@33
|
99 int start = max(0, MAPestimate - limit);
|
andrew@33
|
100 int end = min(MAPestimate + limit, length-1);
|
andrew@33
|
101
|
andrew@33
|
102 integratedEstimate = 0;
|
andrew@33
|
103 double integratedTotal = 0;
|
andrew@33
|
104 for (int i = start;i <= end;i++){
|
andrew@33
|
105 integratedEstimate += array[i]*i;
|
andrew@33
|
106 integratedTotal += array[i];
|
andrew@33
|
107 }
|
andrew@33
|
108 if (integratedTotal > 0){
|
andrew@33
|
109 integratedEstimate /= integratedTotal;
|
andrew@33
|
110 }
|
andrew@33
|
111
|
andrew@33
|
112 }
|
andrew@33
|
113
|
andrew@33
|
114
|
andrew@33
|
115 void DynamicVector::zero(){
|
andrew@33
|
116 for (int i = 0;i < array.size();i++)
|
andrew@33
|
117 array[i] = 0;
|
andrew@33
|
118 }
|
andrew@33
|
119
|
andrew@33
|
120 void DynamicVector::renormalise(){
|
andrew@33
|
121 double tmpMax = getMaximum();
|
andrew@33
|
122 if (tmpMax > 0){
|
andrew@33
|
123 // printf("renormalise : max is %f and size is %i\n", tmpMax, arraySize);
|
andrew@33
|
124 for (int i = 0;i < array.size();i++)
|
andrew@33
|
125 array[i] /= tmpMax;
|
andrew@33
|
126
|
andrew@33
|
127 }
|
andrew@33
|
128 //printArray();
|
andrew@33
|
129 }
|
andrew@33
|
130
|
andrew@33
|
131 void DynamicVector::doProduct(DynamicVector& arrayOne, DynamicVector& arrayTwo){
|
andrew@33
|
132
|
andrew@33
|
133 for (int i = 0;i < arrayOne.length;i++)
|
andrew@33
|
134 array[i] = arrayOne.array[i] * arrayTwo.array[i];
|
andrew@33
|
135 }
|
andrew@33
|
136
|
andrew@33
|
137
|
andrew@33
|
138 void DynamicVector::printArray(){
|
andrew@33
|
139 for (int i = 0;i < arraySize;i++){
|
andrew@33
|
140 printf("[%i] = %f\n", i, array[i]);
|
andrew@33
|
141 }
|
andrew@33
|
142 }
|
andrew@33
|
143
|
andrew@33
|
144 void DynamicVector::translateDistribution(int translationIndex){
|
andrew@33
|
145 int tmpIndex;
|
andrew@33
|
146 DoubleVector tmpArray;
|
andrew@33
|
147 int i;
|
andrew@33
|
148
|
andrew@33
|
149 for (i=0;i < arraySize;i++){
|
andrew@33
|
150 tmpArray.push_back(array[i]);
|
andrew@33
|
151 }
|
andrew@33
|
152 //translate values
|
andrew@33
|
153 for (i=0;i < arraySize;i++){
|
andrew@33
|
154 tmpIndex = (i + translationIndex + arraySize)%arraySize;
|
andrew@33
|
155 array[tmpIndex] = tmpArray[i];
|
andrew@33
|
156 }
|
andrew@33
|
157 tmpArray.clear();
|
andrew@33
|
158 //now delete tmp array
|
andrew@33
|
159 }
|
andrew@33
|
160
|
andrew@33
|
161 void DynamicVector::addGaussianShape(const double& mean, const double& StdDev, double factor){
|
andrew@33
|
162
|
andrew@33
|
163 int i;
|
andrew@33
|
164 double std_dev_factor = (2*StdDev*StdDev);
|
andrew@33
|
165 factor *= (1/(StdDev*sqrt(2*PI)));
|
andrew@33
|
166 int maxVal = min((int) array.size(), (int)(mean + 4.8*StdDev));
|
andrew@33
|
167 int minVal = max(0, (int)(mean - 4.8*StdDev));
|
andrew@33
|
168
|
andrew@33
|
169 for (i=minVal;i < maxVal;i++){
|
andrew@33
|
170 array[i] += factor*exp(-1*(i-mean)*(i-mean)/(std_dev_factor));
|
andrew@33
|
171 }
|
andrew@33
|
172
|
andrew@33
|
173 // addGaussianShapeByLookupTable(mean, StdDev, factor);
|
andrew@33
|
174 }
|
andrew@33
|
175
|
andrew@44
|
176
|
andrew@44
|
177 void DynamicVector::addGaussianShapeFromRealTime(const double& actualTime, const double& StdDev, double factor){
|
andrew@44
|
178
|
andrew@44
|
179 double mean = getRealTermsAsIndex(actualTime);
|
andrew@44
|
180 printf("Gaussian realtime %f at index %f\n", actualTime, mean);
|
andrew@44
|
181 int i;
|
andrew@44
|
182 double std_dev_factor = (2*StdDev*StdDev);
|
andrew@44
|
183 factor *= (1/(StdDev*sqrt(2*PI)));
|
andrew@44
|
184 int maxVal = min((int) array.size(), (int)(mean + 4.8*StdDev));
|
andrew@44
|
185 int minVal = max(0, (int)(mean - 4.8*StdDev));
|
andrew@44
|
186
|
andrew@44
|
187 for (i=minVal;i < maxVal;i++){
|
andrew@44
|
188 array[i] += factor*exp(-1*(i-mean)*(i-mean)/(std_dev_factor));
|
andrew@44
|
189 }
|
andrew@44
|
190
|
andrew@44
|
191 // addGaussianShapeByLookupTable(mean, StdDev, factor);
|
andrew@44
|
192 }
|
andrew@44
|
193
|
andrew@44
|
194
|
andrew@33
|
195 void DynamicVector::addGaussianShapeByLookupTable(double& mean, double& StdDev, double factor){
|
andrew@33
|
196 int i;
|
andrew@33
|
197 int lookupIndex ;
|
andrew@33
|
198 factor *= (1/(StdDev*sqrt(2*PI)));
|
andrew@33
|
199 for (i=0;i<array.size()-1;i++){
|
andrew@33
|
200 lookupIndex = round(getLookupIndex(i, mean, StdDev));
|
andrew@33
|
201 array[i] += factor*gaussianLookupTable[lookupIndex];
|
andrew@33
|
202 }
|
andrew@33
|
203 //printf("ADDED GAUSSIAN SHAPE %i\n", (int)array.size());
|
andrew@33
|
204 }
|
andrew@33
|
205
|
andrew@33
|
206 double DynamicVector::getLookupIndex(const int& i, const double& mean, const double& StdDev){
|
andrew@33
|
207
|
andrew@33
|
208 double Z = ((double)i - mean)/StdDev;
|
andrew@33
|
209 double lookupIndex = Z*gaussianLookupStdDev + gaussianLookupMean;
|
andrew@33
|
210
|
andrew@33
|
211 if (lookupIndex < 0)
|
andrew@33
|
212 lookupIndex = 0;
|
andrew@33
|
213
|
andrew@33
|
214 if (lookupIndex >= GAUSSIAN_LOOKUP_LENGTH)
|
andrew@33
|
215 lookupIndex = GAUSSIAN_LOOKUP_LENGTH-1;
|
andrew@33
|
216
|
andrew@33
|
217 // (i - mean)*(i-mean)*(GAUSSIAN_LOOKUP_LENGTH*GAUSSIAN_LOOKUP_LENGTH/16.0)/(StdDev*StdDev);
|
andrew@33
|
218 return lookupIndex;
|
andrew@33
|
219 }
|
andrew@33
|
220
|
andrew@33
|
221 void DynamicVector::addTriangularShape(double mean, double width, double factor){
|
andrew@33
|
222 int i;
|
andrew@33
|
223
|
andrew@33
|
224 for (i= max(0., (double)(mean - width));i < min((mean+width), (double)array.size());i++){
|
andrew@33
|
225 array[i] += factor * abs(i - mean) / mean;
|
andrew@33
|
226 }
|
andrew@33
|
227
|
andrew@33
|
228 }
|
andrew@33
|
229
|
andrew@33
|
230 void DynamicVector::addConstant(const double& value){
|
andrew@33
|
231 for (int i=0;i<array.size();i++){
|
andrew@33
|
232 array[i] += value;
|
andrew@33
|
233 }
|
andrew@33
|
234 }
|
andrew@33
|
235
|
andrew@33
|
236
|
andrew@33
|
237 void DynamicVector::addToIndex(const int& index, const double& constant){
|
andrew@33
|
238 array[index] += constant;
|
andrew@33
|
239 }
|
andrew@33
|
240
|
andrew@33
|
241
|
andrew@33
|
242 double DynamicVector::getIndexInRealTerms(const int& index){
|
andrew@33
|
243 if (index < arraySize)
|
andrew@33
|
244 return (offset + scalar*index);
|
andrew@33
|
245 else
|
andrew@33
|
246 return 0;
|
andrew@33
|
247 }
|
andrew@33
|
248
|
andrew@33
|
249 double DynamicVector::getRealTermsAsIndex(double value){
|
andrew@33
|
250 value -= offset;
|
andrew@33
|
251 value /= scalar;
|
andrew@33
|
252
|
andrew@33
|
253 return value;
|
andrew@33
|
254
|
andrew@33
|
255 }
|
andrew@33
|
256
|
andrew@33
|
257 double DynamicVector::getValueAtMillis(const double& millis){
|
andrew@33
|
258
|
andrew@33
|
259 int index = round(getRealTermsAsIndex(millis));
|
andrew@33
|
260 if (index >= 0 && index < length)
|
andrew@33
|
261 return array[index];
|
andrew@33
|
262 else
|
andrew@33
|
263 return 0;
|
andrew@33
|
264 }
|
andrew@33
|
265
|
andrew@33
|
266 void DynamicVector::drawVector(const int& minIndex, const int& maxIndex){
|
andrew@33
|
267
|
andrew@33
|
268
|
andrew@33
|
269 double stepSize = ofGetWidth() / (double)(maxIndex - minIndex);
|
andrew@33
|
270 double screenHeight = (double) ofGetHeight();
|
andrew@33
|
271 double maxVal = getMaximum();
|
andrew@33
|
272
|
andrew@33
|
273 int startInt = max(1,minIndex+1);
|
andrew@33
|
274 int endInt = min(maxIndex, (int)array.size());
|
andrew@33
|
275 double heightConstant = screenHeight / maxVal;
|
andrew@33
|
276 int lastHeightPixel = heightConstant * (maxVal - array[startInt-1]);
|
andrew@33
|
277 int newHeightPixel;
|
andrew@33
|
278 for (int i = startInt;i < endInt;i++){
|
andrew@33
|
279 newHeightPixel = (int) heightConstant * (maxVal - array[i]);
|
andrew@44
|
280 int xPos = i - startInt;
|
andrew@44
|
281 ofLine (stepSize*(xPos-1), lastHeightPixel, stepSize*xPos, newHeightPixel);
|
andrew@33
|
282 lastHeightPixel = newHeightPixel;
|
andrew@33
|
283 }
|
andrew@33
|
284
|
andrew@33
|
285 }
|
andrew@33
|
286
|
andrew@33
|
287
|
andrew@33
|
288 void DynamicVector::drawConstrainedVector(const int& minIndex, const int& maxIndex, const int& minScreenIndex, const int& maxScreenIndex){
|
andrew@33
|
289 //constrain the height and width
|
andrew@33
|
290
|
andrew@33
|
291 double stepSize = (maxScreenIndex - minScreenIndex) / (double)(maxIndex - minIndex);//step size in pixels per array bin
|
andrew@33
|
292 double screenHeight = ofGetHeight();
|
andrew@33
|
293 double maxVal = getMaximum();
|
andrew@33
|
294
|
andrew@33
|
295 //OPTIMIZE!! XXX could just add stepsize each time
|
andrew@33
|
296 //not add minindex each time
|
andrew@33
|
297 int i = max(1,minIndex+1);
|
andrew@33
|
298 // ofDrawBitmapString("i = "+ofToString(i)+" :: screen min: "+ofToString(minScreenIndex + stepSize*(i-minIndex-1)), 20, 640);
|
andrew@33
|
299
|
andrew@33
|
300 while ((minScreenIndex + stepSize*(i-minIndex)) < 0)
|
andrew@33
|
301 i++;//only draw what is on the screen
|
andrew@33
|
302
|
andrew@33
|
303 for ( ; i < min(maxIndex+1, (int)array.size());i++){
|
andrew@33
|
304 ofLine (minScreenIndex + (stepSize*(i-minIndex-1)), screenHeight * (1 - array[i-1] / maxVal),
|
andrew@33
|
305 minScreenIndex + (stepSize*(i-minIndex)), screenHeight * (1 - array[i] / maxVal) );
|
andrew@33
|
306
|
andrew@33
|
307 }
|
andrew@33
|
308
|
andrew@33
|
309 ofLine(minScreenIndex, screenHeight, minScreenIndex, screenHeight/2);
|
andrew@33
|
310 ofLine(maxScreenIndex, screenHeight, maxScreenIndex, screenHeight/2);
|
andrew@33
|
311
|
andrew@33
|
312 // ofDrawBitmapString(ofToString(stepSize, 2)+" "+ofToString(maxScreenIndex - minScreenIndex, 0), 20, 600);
|
andrew@33
|
313
|
andrew@33
|
314 }
|