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