Mercurial > hg > midi-score-follower
view hackday/DynamicBayesianArray.cpp @ 36:5a1b0c6fa1fb
Added class to read in the csv Annotation file, then write out the respective difference between the performed piece as followed here, and the annotation of RWC by Ewert and Muller
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Thu, 15 Dec 2011 02:28:49 +0000 |
parents | 49a5b023df1e |
children |
line wrap: on
line source
/* * DynamicDynamicBayesianArray.cpp * midiCannamReader * * Created by Andrew on 17/07/2011. * Copyright 2011 QMUL. All rights reserved. * */ #include "DynamicBayesianArray.h" #include "math.h" #include "ofMain.h" DynamicBayesianArray::DynamicBayesianArray(){ // prior.createVector(240); // likelihood.createVector(240); // posterior.createVector(240); testVector.createVector(240); testVector.addGaussianShape(100,10, 0.1); likelihoodNoise = 0.5; likelihoodMean = ARRAY_SIZE/2; likelihoodStdDev = ARRAY_SIZE / 12; initialiseArray(); } void DynamicBayesianArray::initialiseArray(){ //maximumIndex = 12;//change this setGaussianPrior(ARRAY_SIZE/2, ARRAY_SIZE/1); setGaussianLikelihood(ARRAY_SIZE/2, ARRAY_SIZE/1);//likelihoodMean, likelihoodStdDev); calculatePosterior(); renormalisePosterior(); posteriorDecayRate = 0.06; eighthNoteProportion = 0.35;//must be less than 0.5 to discriminate - was 0.4 earlySixteenthNoteProportion = 0; lateSixteenthNoteProportion = 0; decayNoiseAmount = 0.1; decayNoiseStdDev = ARRAY_SIZE/24; standardDeviation = likelihoodStdDev; setDecayNoiseGaussian(ARRAY_SIZE/2, decayNoiseStdDev); setGaussianLikelihood(likelihoodMean, likelihoodStdDev); } void DynamicBayesianArray::setGaussianPrior(float mean, float StdDev){ int i; for (i=0;i<ARRAY_SIZE;i++){ prior[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)); //posterior[i] = prior[i]; } } void DynamicBayesianArray::setGaussianPosterior(float mean, float StdDev){ int i; for (i=0;i<ARRAY_SIZE;i++){ posterior[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)); } } void DynamicBayesianArray::setGaussianLikelihood(float mean, float StdDev){ if (mean >= 0 && mean <= ARRAY_SIZE){ int i; float eighthDifference; int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE; float mainDifference; float gaussianProportion = 1 - likelihoodNoise; for (i=0;i < ARRAY_SIZE;i++){ mainDifference = min( double(fabs(i-mean)) , (double)(i + ARRAY_SIZE - mean)); //without * (1 - eighthNoteProportion) likelihood[i] = gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ; likelihood[i] += (likelihoodNoise / ARRAY_SIZE); //likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) , //(double) (likelihoodNoise / ARRAY_SIZE) ); } // renormaliseArray(&likelihood[0], ARRAY_SIZE); }//end if mean within limits } void DynamicBayesianArray::calculatePosterior(){ int i; for (i=0;i < ARRAY_SIZE;i++){ posterior[i] = likelihood[i] * prior[i]; } //renormalisePosterior(); } float DynamicBayesianArray::getMaximum(float *ptr, int length){ int i; float max = 0; for (i=0;i < length;i++){ if (*(ptr+i)>max) max = *(ptr+i); } maximumValue = max; return max; } float* DynamicBayesianArray::getMaximumEstimate(float *ptr, int length){ float returnArray[2]; int i; float max = 0; maximumIndex = 0; for (i=0;i < length;i++){ if (*(ptr+i)>max){ max = *(ptr+i); maximumIndex = i; } } returnArray[0] = max; returnArray[1] = maximumIndex; maximumValue = max; return &returnArray[0]; } double DynamicBayesianArray::getIntegratedEstimateIndex(){ int i; float integratedQuantity = 0; float integratedTotal = 0; double integratedIndex = 0; for (i=0;i < ARRAY_SIZE;i++){ integratedQuantity += posterior[i];//the values of the probability distribution integratedTotal += i*posterior[i]; } if (integratedQuantity > 0){ integratedIndex = integratedTotal / integratedQuantity; } integratedEstimate = (float) integratedIndex; return integratedIndex; } double DynamicBayesianArray::calculateStandardDeviation(){ double total = 0; double pdfSum; double variance = 0; for (int i=0;i < ARRAY_SIZE;i++){ //*posterior[i] * total += posterior[i] * (i - integratedEstimate) * (i - integratedEstimate);//the values of the probability distribution pdfSum += posterior[i]; } if (pdfSum > 0) variance = total / pdfSum; else variance = ARRAY_SIZE; standardDeviation = sqrt(variance); return standardDeviation; } void DynamicBayesianArray::renormaliseArray(float *ptr, int length){ int i; float totalArea = 0; for (i=0;i < length;i++){ totalArea += *(ptr+i); } for (i=0;i < length;i++){ *(ptr+i) /= totalArea; } } void DynamicBayesianArray::resetPrior(){ int i; for (i=0;i<ARRAY_SIZE;i++){ prior[i] = posterior[i]; } } void DynamicBayesianArray::renormalisePosterior(){ int i; float totalArea = 0; for (i=0;i < ARRAY_SIZE;i++){ totalArea += posterior[i]; } for (i=0;i < ARRAY_SIZE;i++){ posterior[i] /= totalArea; } } void DynamicBayesianArray::decayPosterior(){ float *pointer; pointer = getMaximumEstimate(&posterior[0], ARRAY_SIZE); float maximum; maximum = *pointer; int i; for (i=0;i<ARRAY_SIZE;i++){ posterior[i] += (maximum - posterior[i]) * posteriorDecayRate * 0.01;;//usded to be * maximum not minus value } maximumIndex = *(pointer+1); } void DynamicBayesianArray::setDecayNoiseGaussian(float mean, float StdDev){ int i; for (i=0;i<ARRAY_SIZE;i++){ decayNoiseArray[i] = (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)); } } void DynamicBayesianArray::decayPosteriorWithGaussianNoise(){ int i; float currentMaximum = getMaximum(&posterior[0], ARRAY_SIZE); for (i=0;i<ARRAY_SIZE;i++){ posterior[i] += decayNoiseArray[(i - (int)maximumIndex + ((3*ARRAY_SIZE)/2)) % ARRAY_SIZE] * currentMaximum * decayNoiseAmount; //posteriorDecayRate * 0.01;;//usded to be * maximum not minus value } } void DynamicBayesianArray::resetMaximumPosterior(){ int i; float max = 0; for (i=0;i < ARRAY_SIZE;i++){ if (posterior[i]>max){ maximumIndex = i; max = posterior[i]; } } } void DynamicBayesianArray::translateDistribution(int translationIndex){ int tmpIndex; //copy array int i; for (i=0;i < ARRAY_SIZE;i++){ tempPosteriorArray[i] = posterior[i] ; } //translate values for (i=0;i < ARRAY_SIZE;i++){ tmpIndex = (i + translationIndex + ARRAY_SIZE)%ARRAY_SIZE; posterior[tmpIndex] = tempPosteriorArray[i]; } //now delete tmp array } void DynamicBayesianArray::drawFloatArray(float* arrayToDraw, const int& minIndex, const int& maxIndex){ if (minIndex >= 0){ double stepSize = ofGetWidth() / (double)(maxIndex - minIndex); double screenHeight = ofGetHeight(); double maxVal = getMaximum(&arrayToDraw[0], maxIndex); for (int i = minIndex+1;i < maxIndex;i++){ ofLine (stepSize*(i-1), screenHeight * (1 - arrayToDraw[i-1] / maxVal), stepSize*i, screenHeight * (1 - arrayToDraw[i] / maxVal) ); } } } /* void DynamicBayesianArray::drawDoubleArray(double[]& arrayToDraw, const int& minIndex, const int& maxIndex){ if (minIndex >= 0 && maxIndex <= arrayToDraw.size(0)) } */ /* void DynamicBayesianArray::setGaussianLikelihoodForBeats(float mean, float StdDev){ //this has eighth and sixteenth positions included if (mean >= 0 && mean <= ARRAY_SIZE){ int i; float eighthDifference; int eighthPosition = ((int)mean + ARRAY_SIZE/2)%ARRAY_SIZE; int earlySixteenthPosition = ((int)mean + (3*ARRAY_SIZE/4))%ARRAY_SIZE;; int lateSixteenthPosition = ((int)mean + (ARRAY_SIZE/4))%ARRAY_SIZE;; float mainDifference, sixteenthDifference; float gaussianProportion = 1 - likelihoodNoise; float mainProportion = (1 - eighthNoteProportion - earlySixteenthNoteProportion - lateSixteenthNoteProportion); for (i=0;i < ARRAY_SIZE;i++){ mainDifference = min( fabs(i-mean) , (double)(i + ARRAY_SIZE - mean)); likelihood[i] = gaussianProportion * mainProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(mainDifference)*(mainDifference)/(2*StdDev*StdDev)) ; eighthDifference = min( abs(i - eighthPosition) , i + ARRAY_SIZE - eighthPosition); eighthDifference = min(eighthDifference , (float)(ARRAY_SIZE + eighthPosition - i )); //for e.g. +0.43, or -0.47 we require the gaussian around the half note too likelihood[i] += gaussianProportion * eighthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(eighthDifference)*(eighthDifference)/(2*StdDev*StdDev)) ; sixteenthDifference = min( abs(i - earlySixteenthPosition) , i + ARRAY_SIZE - earlySixteenthPosition); sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + earlySixteenthPosition - i )); //for e.g. +0.43, or -0.47 we require the gaussian around the half note too likelihood[i] += gaussianProportion * earlySixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ; sixteenthDifference = min( abs(i - lateSixteenthPosition) , i + ARRAY_SIZE - lateSixteenthPosition); sixteenthDifference = min(sixteenthDifference , (float)(ARRAY_SIZE + lateSixteenthPosition - i )); //for e.g. +0.43, or -0.47 we require the gaussian around the half note too likelihood[i] += gaussianProportion * lateSixteenthNoteProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(sixteenthDifference)*(sixteenthDifference)/(2*StdDev*StdDev)) ; likelihood[i] += (likelihoodNoise / ARRAY_SIZE); //likelihood[i] = (float) max(gaussianProportion * (1/(StdDev*sqrt(2*PI)))*exp(-1*(i-mean)*(i-mean)/(2*StdDev*StdDev)) , //(double) (likelihoodNoise / ARRAY_SIZE) ); } // renormaliseArray(&likelihood[0], ARRAY_SIZE); }//end if mean within limits } */