andrew@0: /* andrew@0: * DynamicVector.cpp andrew@0: * midiCannamReader andrew@0: * andrew@0: * Created by Andrew on 18/07/2011. andrew@0: * Copyright 2011 QMUL. All rights reserved. andrew@0: * andrew@0: */ andrew@0: andrew@0: andrew@0: #include "DynamicVector.h" andrew@0: andrew@50: bool printOutput = false; andrew@50: andrew@0: DynamicVector::DynamicVector(){ andrew@0: length = 0; andrew@0: arraySize = 0; andrew@0: maximumValue = 0; andrew@0: MAPestimate = 0; andrew@0: offset = 0; andrew@36: scalar = 6; andrew@0: integratedEstimate = length/2; andrew@0: andrew@0: gaussianLookupMean = (double) GAUSSIAN_LOOKUP_LENGTH/2; andrew@0: gaussianLookupStdDev = (double)(GAUSSIAN_LOOKUP_LENGTH/16); andrew@0: double factor = 1.0;//(1.0 / (gaussianLookupStdDev*sqrt(2*PI)) );//1.0;//-1.0/(2*PI*sqrt(gaussianLookupStdDev)); andrew@0: for (int i = 0;i < GAUSSIAN_LOOKUP_LENGTH;i++){ andrew@0: gaussianLookupTable[i] = factor*exp(-1.0*(i-gaussianLookupMean)*(i-gaussianLookupMean)/(2.0*gaussianLookupStdDev*gaussianLookupStdDev)); andrew@0: } andrew@0: andrew@0: } andrew@0: andrew@0: void DynamicVector::copyFromDynamicVector(const DynamicVector& dynamicVec){ andrew@3: andrew@0: if (dynamicVec.length == length){ andrew@3: offset = dynamicVec.offset; andrew@0: for (int i = 0;i < length;i++) andrew@0: array[i] = dynamicVec.array[i]; andrew@0: } andrew@0: else{ andrew@0: printf("CANNOT COPY VECTORS OF NON SAME LENGTH!!\n"); andrew@0: } andrew@0: } andrew@0: andrew@0: void DynamicVector::createVector(int len){ andrew@0: array.clear(); andrew@0: for (int i = 0; i < len;i++){ andrew@0: array.push_back(0); andrew@0: } andrew@0: length = len; andrew@0: arraySize = array.size(); andrew@0: integratedEstimate = length/2; andrew@0: } andrew@0: andrew@0: andrew@0: double DynamicVector::getMaximum(){ andrew@0: int i; andrew@0: double max = 0; andrew@0: for (i=0;i < length;i++){ andrew@0: if (array[i] > max){ andrew@0: max = array[i]; andrew@0: MAPestimate = i; andrew@0: } andrew@0: } andrew@0: maximumValue = max; andrew@0: return max; andrew@0: } andrew@0: andrew@4: int DynamicVector::getMAPestimate(){ andrew@4: int i; andrew@4: double max = 0; andrew@4: for (i=0;i < length;i++){ andrew@4: if (array[i] > max){ andrew@4: max = array[i]; andrew@4: MAPestimate = i; andrew@4: } andrew@4: } andrew@4: maximumValue = max; andrew@4: return MAPestimate; andrew@4: } andrew@4: andrew@0: double DynamicVector::getIntegratedEstimate(){ andrew@0: //returns the index of the integrated average - where the probability distribution is centred andrew@0: integratedEstimate = 0; andrew@0: double integratedTotal = 0; andrew@0: for (int i = 0;i < length;i++){ andrew@0: integratedEstimate += array[i]*i; andrew@0: integratedTotal += array[i]; andrew@0: } andrew@0: if (integratedTotal > 0){ andrew@0: integratedEstimate /= integratedTotal; andrew@0: } andrew@0: return integratedEstimate; andrew@0: } andrew@0: andrew@0: void DynamicVector::updateIntegratedEstimate(){ andrew@0: //returns the index of the integrated average - where the probability distribution is centred andrew@0: integratedEstimate = 0; andrew@0: double integratedTotal = 0; andrew@0: for (int i = 0;i < length;i++){ andrew@0: integratedEstimate += array[i]*i; andrew@0: integratedTotal += array[i]; andrew@0: } andrew@0: if (integratedTotal > 0){ andrew@0: integratedEstimate /= integratedTotal; andrew@0: } andrew@0: andrew@0: } andrew@0: andrew@0: void DynamicVector::updateLimitedIntegratedEstimate(){ andrew@0: //returns the index of the integrated average - where the probability distribution is centred andrew@0: //but limited round the MAP estimate andrew@0: double tmp = getMaximum(); andrew@0: int limit = min(MAPestimate, length - MAPestimate); andrew@0: int start = max(0, MAPestimate - limit); andrew@0: int end = min(MAPestimate + limit, length-1); andrew@0: andrew@0: integratedEstimate = 0; andrew@0: double integratedTotal = 0; andrew@0: for (int i = start;i <= end;i++){ andrew@0: integratedEstimate += array[i]*i; andrew@0: integratedTotal += array[i]; andrew@0: } andrew@0: if (integratedTotal > 0){ andrew@0: integratedEstimate /= integratedTotal; andrew@0: } andrew@0: andrew@0: } andrew@0: andrew@0: andrew@0: void DynamicVector::zero(){ andrew@0: for (int i = 0;i < array.size();i++) andrew@0: array[i] = 0; andrew@0: } andrew@0: andrew@0: void DynamicVector::renormalise(){ andrew@0: double tmpMax = getMaximum(); andrew@0: if (tmpMax > 0){ andrew@0: // printf("renormalise : max is %f and size is %i\n", tmpMax, arraySize); andrew@0: for (int i = 0;i < array.size();i++) andrew@0: array[i] /= tmpMax; andrew@0: andrew@0: } andrew@0: //printArray(); andrew@0: } andrew@0: andrew@0: void DynamicVector::doProduct(DynamicVector& arrayOne, DynamicVector& arrayTwo){ andrew@0: andrew@0: for (int i = 0;i < arrayOne.length;i++) andrew@0: array[i] = arrayOne.array[i] * arrayTwo.array[i]; andrew@0: } andrew@0: andrew@0: andrew@0: void DynamicVector::printArray(){ andrew@0: for (int i = 0;i < arraySize;i++){ andrew@0: printf("[%i] = %f\n", i, array[i]); andrew@0: } andrew@0: } andrew@0: andrew@0: void DynamicVector::translateDistribution(int translationIndex){ andrew@0: int tmpIndex; andrew@0: DoubleVector tmpArray; andrew@0: int i; andrew@0: andrew@0: for (i=0;i < arraySize;i++){ andrew@0: tmpArray.push_back(array[i]); andrew@0: } andrew@0: //translate values andrew@0: for (i=0;i < arraySize;i++){ andrew@0: tmpIndex = (i + translationIndex + arraySize)%arraySize; andrew@0: array[tmpIndex] = tmpArray[i]; andrew@0: } andrew@0: tmpArray.clear(); andrew@0: //now delete tmp array andrew@0: } andrew@0: andrew@2: andrew@2: andrew@2: void DynamicVector::addGaussianShapeFromRealTime(const double& actualTime, const double& StdDev, double factor){ andrew@20: //could be further optimised andrew@2: double mean = getRealTermsAsIndex(actualTime); andrew@20: double standardDeviation = StdDev / scalar;//in vector indices from real time (ms) andrew@20: //printf("Gaussian realtime %f at index %f std dev %f vec indices %f\n", actualTime, mean, StdDev, standardDeviation ); andrew@2: int i; andrew@20: double std_dev_factor = (2*standardDeviation*standardDeviation); andrew@20: factor *= (1/(standardDeviation*sqrt(2*PI))); andrew@20: int maxVal = min((int) array.size(), (int)(mean + 4.8*standardDeviation)); andrew@20: int minVal = max(0, (int)(mean - 4.8*standardDeviation)); andrew@2: andrew@2: for (i=minVal;i < maxVal;i++){ andrew@2: array[i] += factor*exp(-1*(i-mean)*(i-mean)/(std_dev_factor)); andrew@2: } andrew@2: andrew@2: // addGaussianShapeByLookupTable(mean, StdDev, factor); andrew@2: } andrew@2: andrew@2: andrew@0: void DynamicVector::addGaussianShape(const double& mean, const double& StdDev, double factor){ andrew@0: andrew@0: int i; andrew@0: double std_dev_factor = (2*StdDev*StdDev); andrew@0: factor *= (1/(StdDev*sqrt(2*PI))); andrew@0: int maxVal = min((int) array.size(), (int)(mean + 4.8*StdDev)); andrew@0: int minVal = max(0, (int)(mean - 4.8*StdDev)); andrew@0: andrew@0: for (i=minVal;i < maxVal;i++){ andrew@0: array[i] += factor*exp(-1*(i-mean)*(i-mean)/(std_dev_factor)); andrew@0: } andrew@0: andrew@0: // addGaussianShapeByLookupTable(mean, StdDev, factor); andrew@0: } andrew@0: andrew@0: void DynamicVector::addGaussianShapeByLookupTable(double& mean, double& StdDev, double factor){ andrew@0: int i; andrew@0: int lookupIndex ; andrew@0: factor *= (1/(StdDev*sqrt(2*PI))); andrew@0: for (i=0;i= GAUSSIAN_LOOKUP_LENGTH) andrew@0: lookupIndex = GAUSSIAN_LOOKUP_LENGTH-1; andrew@0: andrew@0: // (i - mean)*(i-mean)*(GAUSSIAN_LOOKUP_LENGTH*GAUSSIAN_LOOKUP_LENGTH/16.0)/(StdDev*StdDev); andrew@0: return lookupIndex; andrew@0: } andrew@0: andrew@0: void DynamicVector::addTriangularShape(double mean, double width, double factor){ andrew@0: int i; andrew@0: andrew@0: for (i= max(0., (double)(mean - width));i < min((mean+width), (double)array.size());i++){ andrew@0: array[i] += factor * abs(i - mean) / mean; andrew@0: } andrew@0: andrew@0: } andrew@0: andrew@0: void DynamicVector::addConstant(const double& value){ andrew@0: for (int i=0;i= 0 && index < length) andrew@0: return array[index]; andrew@0: else andrew@0: return 0; andrew@0: } andrew@0: andrew@15: andrew@15: double DynamicVector::millisToVectorUnits(const double& millis){ andrew@15: return millis/scalar; andrew@15: } andrew@15: andrew@52: #pragma mark -draw andrew@52: andrew@0: void DynamicVector::drawVector(const int& minIndex, const int& maxIndex){ andrew@0: andrew@0: andrew@0: double stepSize = ofGetWidth() / (double)(maxIndex - minIndex); andrew@0: double screenHeight = (double) ofGetHeight(); andrew@0: double maxVal = getMaximum(); andrew@0: andrew@0: int startInt = max(1,minIndex+1); andrew@0: int endInt = min(maxIndex, (int)array.size()); andrew@0: double heightConstant = screenHeight / maxVal; andrew@0: int lastHeightPixel = heightConstant * (maxVal - array[startInt-1]); andrew@0: int newHeightPixel; andrew@0: for (int i = startInt;i < endInt;i++){ andrew@0: newHeightPixel = (int) heightConstant * (maxVal - array[i]); andrew@3: int xPos = i - startInt; andrew@3: ofLine (stepSize*(xPos-1), lastHeightPixel, stepSize*xPos, newHeightPixel); andrew@0: lastHeightPixel = newHeightPixel; andrew@0: } andrew@0: andrew@0: } andrew@0: andrew@0: andrew@0: void DynamicVector::drawVector(const int& minIndex, const int& maxIndex, ofxWindowRegion window){ andrew@0: andrew@0: andrew@0: double stepSize = window.width / (double)(maxIndex - minIndex); andrew@0: double screenHeight = (double) window.height; andrew@0: double maxVal = getMaximum(); andrew@0: andrew@0: int startInt = max(1,minIndex+1); andrew@0: int endInt = min(maxIndex, (int)array.size()); andrew@0: double heightConstant = screenHeight / maxVal; andrew@0: int lastHeightPixel = heightConstant * (maxVal - array[startInt-1]); andrew@0: int newHeightPixel; andrew@0: for (int i = startInt;i < endInt;i++){ andrew@0: newHeightPixel = (int) heightConstant * (maxVal - array[i]); andrew@3: int xPos = i - startInt; andrew@3: ofLine (window.x+stepSize*(xPos-1), window.y+lastHeightPixel, window.x+stepSize*xPos, window.y+newHeightPixel); andrew@0: lastHeightPixel = newHeightPixel; andrew@0: } andrew@3: ofDrawBitmapString("start index "+ofToString(startInt)+" end "+ofToString(endInt), window.x+20, window.y+20); andrew@0: } andrew@0: andrew@0: andrew@0: void DynamicVector::drawConstrainedVector(const int& minIndex, const int& maxIndex, const int& minScreenIndex, const int& maxScreenIndex){ andrew@0: //constrain the height and width andrew@0: andrew@0: double stepSize = (maxScreenIndex - minScreenIndex) / (double)(maxIndex - minIndex);//step size in pixels per array bin andrew@0: double screenHeight = ofGetHeight(); andrew@0: double maxVal = getMaximum(); andrew@6: andrew@0: //OPTIMIZE!! XXX could just add stepsize each time andrew@0: //not add minindex each time andrew@0: int i = max(1,minIndex+1); andrew@6: // ofDrawBitmapString("i = "+ofToString(i)+" :: screen min: "+ofToString(minScreenIndex + stepSize*(i-minIndex-1)), 20, 640); andrew@0: andrew@0: while ((minScreenIndex + stepSize*(i-minIndex)) < 0) andrew@0: i++;//only draw what is on the screen andrew@0: andrew@0: for ( ; i < min(maxIndex+1, (int)array.size());i++){ andrew@0: ofLine (minScreenIndex + (stepSize*(i-minIndex-1)), screenHeight * (1 - array[i-1] / maxVal), andrew@0: minScreenIndex + (stepSize*(i-minIndex)), screenHeight * (1 - array[i] / maxVal) ); andrew@0: andrew@0: } andrew@0: andrew@0: ofLine(minScreenIndex, screenHeight, minScreenIndex, screenHeight/2); andrew@0: ofLine(maxScreenIndex, screenHeight, maxScreenIndex, screenHeight/2); andrew@0: andrew@6: // ofDrawBitmapString(ofToString(stepSize, 2)+" "+ofToString(maxScreenIndex - minScreenIndex, 0), 20, 600); andrew@6: andrew@6: } andrew@6: andrew@6: andrew@6: void DynamicVector::drawConstrainedVector(const int& minIndex, const int& maxIndex, const int& minScreenIndex, const int& maxScreenIndex, const ofxWindowRegion& window){ andrew@6: //constrain the height and width andrew@6: andrew@6: double stepSize = (maxScreenIndex - minScreenIndex) / (double)(maxIndex - minIndex);//step size in pixels per array bin andrew@6: double screenHeight = window.height; andrew@6: double maxVal = getMaximum(); andrew@6: andrew@6: //OPTIMIZE!! XXX could just add stepsize each time andrew@6: //not add minindex each time andrew@6: int i = max(1,minIndex+1); andrew@6: // ofDrawBitmapString("i = "+ofToString(i)+" :: screen min: "+ofToString(minScreenIndex + stepSize*(i-minIndex-1)), 20, 640); andrew@6: andrew@6: while ((minScreenIndex + stepSize*(i-minIndex)) < 0) andrew@6: i++;//only draw what is on the screen andrew@6: andrew@6: for ( ; i < min(maxIndex+1, (int)array.size());i++){ andrew@6: ofLine (window.x+minScreenIndex + (stepSize*(i-minIndex-1)), window.y + screenHeight * (1 - array[i-1] / maxVal), andrew@6: window.x + minScreenIndex + (stepSize*(i-minIndex)), window.y + screenHeight * (1 - array[i] / maxVal) ); andrew@6: andrew@6: } andrew@6: andrew@6: //some lines where the bounaries are andrew@6: ofLine(window.x + minScreenIndex, window.y + screenHeight, window.x + minScreenIndex, window.y + screenHeight/2); andrew@6: ofLine(window.x + maxScreenIndex, window.y + screenHeight, window.x + maxScreenIndex, window.y + screenHeight/2); andrew@6: andrew@50: /* andrew@50: string infoString = "max "+ofToString(maxVal); andrew@50: infoString += "\n offset "+ofToString(offset); andrew@50: ofDrawBitmapString(infoString, window.x + window.width/2, window.y + 15); andrew@50: */ andrew@0: // ofDrawBitmapString(ofToString(stepSize, 2)+" "+ofToString(maxScreenIndex - minScreenIndex, 0), 20, 600); andrew@0: andrew@0: }