andrew@0: /* andrew@0: * DynamicDynamicBayesianArray.cpp andrew@0: * midiCannamReader andrew@0: * andrew@0: * Created by Andrew on 17/07/2011. andrew@0: * Copyright 2011 QMUL. All rights reserved. andrew@0: * andrew@0: */ andrew@0: andrew@0: #include "DynamicBayesianArray.h" andrew@0: #include "math.h" andrew@0: #include "ofMain.h" andrew@0: andrew@0: DynamicBayesianArray::DynamicBayesianArray(){ andrew@0: andrew@0: // prior.createVector(240); andrew@0: // likelihood.createVector(240); andrew@0: // posterior.createVector(240); andrew@0: testVector.createVector(240); andrew@0: testVector.addGaussianShape(100,10, 0.1); andrew@0: andrew@0: andrew@0: likelihoodNoise = 0.5; andrew@0: likelihoodMean = ARRAY_SIZE/2; andrew@0: likelihoodStdDev = ARRAY_SIZE / 12; andrew@0: initialiseArray(); andrew@0: } andrew@0: andrew@0: void DynamicBayesianArray::initialiseArray(){ andrew@0: andrew@0: //maximumIndex = 12;//change this andrew@0: setGaussianPrior(ARRAY_SIZE/2, ARRAY_SIZE/1); andrew@0: setGaussianLikelihood(ARRAY_SIZE/2, ARRAY_SIZE/1);//likelihoodMean, likelihoodStdDev); andrew@0: andrew@0: calculatePosterior(); andrew@0: renormalisePosterior(); andrew@0: posteriorDecayRate = 0.06; andrew@0: andrew@0: eighthNoteProportion = 0.35;//must be less than 0.5 to discriminate - was 0.4 andrew@0: earlySixteenthNoteProportion = 0; andrew@0: lateSixteenthNoteProportion = 0; andrew@0: decayNoiseAmount = 0.1; andrew@0: decayNoiseStdDev = ARRAY_SIZE/24; andrew@0: standardDeviation = likelihoodStdDev; andrew@0: setDecayNoiseGaussian(ARRAY_SIZE/2, decayNoiseStdDev); andrew@0: andrew@0: setGaussianLikelihood(likelihoodMean, likelihoodStdDev); andrew@0: } andrew@0: andrew@0: andrew@0: void DynamicBayesianArray::setGaussianPrior(float mean, float StdDev){ andrew@0: int i; andrew@0: for (i=0;i= 0 && mean <= ARRAY_SIZE){ andrew@0: int i; float eighthDifference; andrew@0: int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE; andrew@0: float mainDifference; andrew@0: float gaussianProportion = 1 - likelihoodNoise; andrew@0: andrew@0: for (i=0;i < ARRAY_SIZE;i++){ andrew@0: andrew@0: mainDifference = min( double(fabs(i-mean)) , (double)(i + ARRAY_SIZE - mean)); andrew@0: //without * (1 - eighthNoteProportion) andrew@0: likelihood[i] = gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ; andrew@0: andrew@0: likelihood[i] += (likelihoodNoise / ARRAY_SIZE); andrew@0: //likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) , andrew@0: //(double) (likelihoodNoise / ARRAY_SIZE) ); andrew@0: } andrew@0: // renormaliseArray(&likelihood[0], ARRAY_SIZE); andrew@0: }//end if mean within limits andrew@0: } andrew@0: andrew@0: void DynamicBayesianArray::calculatePosterior(){ andrew@0: int i; andrew@0: for (i=0;i < ARRAY_SIZE;i++){ andrew@0: posterior[i] = likelihood[i] * prior[i]; andrew@0: } andrew@0: //renormalisePosterior(); andrew@0: } andrew@0: andrew@0: andrew@0: float DynamicBayesianArray::getMaximum(float *ptr, int length){ andrew@0: int i; andrew@0: float max = 0; andrew@0: for (i=0;i < length;i++){ andrew@0: if (*(ptr+i)>max) andrew@0: max = *(ptr+i); andrew@0: } andrew@0: maximumValue = max; andrew@0: return max; andrew@0: } andrew@0: andrew@0: float* DynamicBayesianArray::getMaximumEstimate(float *ptr, int length){ andrew@0: float returnArray[2]; andrew@0: int i; andrew@0: float max = 0; andrew@0: maximumIndex = 0; andrew@0: for (i=0;i < length;i++){ andrew@0: if (*(ptr+i)>max){ andrew@0: max = *(ptr+i); andrew@0: maximumIndex = i; andrew@0: } andrew@0: } andrew@0: returnArray[0] = max; andrew@0: returnArray[1] = maximumIndex; andrew@0: maximumValue = max; andrew@0: return &returnArray[0]; andrew@0: } andrew@0: andrew@0: andrew@0: andrew@0: double DynamicBayesianArray::getIntegratedEstimateIndex(){ andrew@0: int i; andrew@0: float integratedQuantity = 0; andrew@0: float integratedTotal = 0; andrew@0: double integratedIndex = 0; andrew@0: for (i=0;i < ARRAY_SIZE;i++){ andrew@0: integratedQuantity += posterior[i];//the values of the probability distribution andrew@0: integratedTotal += i*posterior[i]; andrew@0: } andrew@0: if (integratedQuantity > 0){ andrew@0: integratedIndex = integratedTotal / integratedQuantity; andrew@0: } andrew@0: integratedEstimate = (float) integratedIndex; andrew@0: return integratedIndex; andrew@0: } andrew@0: andrew@0: andrew@0: double DynamicBayesianArray::calculateStandardDeviation(){ andrew@0: andrew@0: double total = 0; andrew@0: double pdfSum; andrew@0: double variance = 0; andrew@0: for (int i=0;i < ARRAY_SIZE;i++){ andrew@0: //*posterior[i] * andrew@0: total += posterior[i] * (i - integratedEstimate) * (i - integratedEstimate);//the values of the probability distribution andrew@0: pdfSum += posterior[i]; andrew@0: } andrew@0: andrew@0: if (pdfSum > 0) andrew@0: variance = total / pdfSum; andrew@0: else andrew@0: variance = ARRAY_SIZE; andrew@0: andrew@0: standardDeviation = sqrt(variance); andrew@0: return standardDeviation; andrew@0: } andrew@0: andrew@0: andrew@0: andrew@0: void DynamicBayesianArray::renormaliseArray(float *ptr, int length){ andrew@0: int i; andrew@0: float totalArea = 0; andrew@0: for (i=0;i < length;i++){ andrew@0: totalArea += *(ptr+i); andrew@0: } andrew@0: andrew@0: for (i=0;i < length;i++){ andrew@0: *(ptr+i) /= totalArea; andrew@0: } andrew@0: andrew@0: } andrew@0: andrew@0: void DynamicBayesianArray::resetPrior(){ andrew@0: int i; andrew@0: for (i=0;imax){ andrew@0: maximumIndex = i; andrew@0: max = posterior[i]; andrew@0: } andrew@0: } andrew@0: } andrew@0: andrew@0: void DynamicBayesianArray::translateDistribution(int translationIndex){ andrew@0: int tmpIndex; andrew@0: //copy array andrew@0: int i; andrew@0: for (i=0;i < ARRAY_SIZE;i++){ andrew@0: tempPosteriorArray[i] = posterior[i] ; andrew@0: } andrew@0: //translate values andrew@0: for (i=0;i < ARRAY_SIZE;i++){ andrew@0: tmpIndex = (i + translationIndex + ARRAY_SIZE)%ARRAY_SIZE; andrew@0: posterior[tmpIndex] = tempPosteriorArray[i]; andrew@0: } andrew@0: //now delete tmp array andrew@0: } andrew@0: andrew@0: andrew@0: void DynamicBayesianArray::drawFloatArray(float* arrayToDraw, const int& minIndex, const int& maxIndex){ andrew@0: andrew@0: if (minIndex >= 0){ andrew@0: andrew@0: double stepSize = ofGetWidth() / (double)(maxIndex - minIndex); andrew@0: double screenHeight = ofGetHeight(); andrew@0: double maxVal = getMaximum(&arrayToDraw[0], maxIndex); andrew@0: andrew@0: for (int i = minIndex+1;i < maxIndex;i++){ andrew@0: andrew@0: ofLine (stepSize*(i-1), screenHeight * (1 - arrayToDraw[i-1] / maxVal), stepSize*i, screenHeight * (1 - arrayToDraw[i] / maxVal) ); andrew@0: } andrew@0: andrew@0: } andrew@0: andrew@0: andrew@0: } andrew@0: andrew@0: andrew@0: andrew@0: /* andrew@0: void DynamicBayesianArray::drawDoubleArray(double[]& arrayToDraw, const int& minIndex, const int& maxIndex){ andrew@0: andrew@0: if (minIndex >= 0 && maxIndex <= arrayToDraw.size(0)) andrew@0: andrew@0: } andrew@0: */ andrew@0: /* andrew@0: void DynamicBayesianArray::setGaussianLikelihoodForBeats(float mean, float StdDev){ andrew@0: //this has eighth and sixteenth positions included andrew@0: andrew@0: if (mean >= 0 && mean <= ARRAY_SIZE){ andrew@0: int i; float eighthDifference; andrew@0: int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE; andrew@0: int earlySixteenthPosition = ((int)mean + (3*ARRAY_SIZE/4))%ARRAY_SIZE;; andrew@0: int lateSixteenthPosition = ((int)mean + (ARRAY_SIZE/4))%ARRAY_SIZE;; andrew@0: andrew@0: float mainDifference, sixteenthDifference; andrew@0: float gaussianProportion = 1 - likelihoodNoise; andrew@0: float mainProportion = (1 - eighthNoteProportion - earlySixteenthNoteProportion - lateSixteenthNoteProportion); andrew@0: andrew@0: for (i=0;i < ARRAY_SIZE;i++){ andrew@0: andrew@0: mainDifference = min( fabs(i-mean) , (double)(i + ARRAY_SIZE - mean)); andrew@0: likelihood[i] = gaussianProportion * mainProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ; andrew@0: andrew@0: eighthDifference = min( abs(i - eighthPosition) , i + ARRAY_SIZE - eighthPosition); andrew@0: eighthDifference = min(eighthDifference , (float)(ARRAY_SIZE + eighthPosition - i )); andrew@0: //for e.g. +0.43, or -0.47 we require the gaussian around the half note too andrew@0: likelihood[i] += gaussianProportion * eighthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(eighthDifference)*(eighthDifference)/(2*StdDev*StdDev)) ; andrew@0: andrew@0: sixteenthDifference = min( abs(i - earlySixteenthPosition) , i + ARRAY_SIZE - earlySixteenthPosition); andrew@0: sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + earlySixteenthPosition - i )); andrew@0: //for e.g. +0.43, or -0.47 we require the gaussian around the half note too andrew@0: likelihood[i] += gaussianProportion * earlySixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ; andrew@0: andrew@0: sixteenthDifference = min( abs(i - lateSixteenthPosition) , i + ARRAY_SIZE - lateSixteenthPosition); andrew@0: sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + lateSixteenthPosition - i )); andrew@0: //for e.g. +0.43, or -0.47 we require the gaussian around the half note too andrew@0: likelihood[i] += gaussianProportion * lateSixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ; andrew@0: andrew@0: andrew@0: andrew@0: likelihood[i] += (likelihoodNoise / ARRAY_SIZE); andrew@0: //likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) , andrew@0: //(double) (likelihoodNoise / ARRAY_SIZE) ); andrew@0: } andrew@0: // renormaliseArray(&likelihood[0], ARRAY_SIZE); andrew@0: }//end if mean within limits andrew@0: } andrew@0: */