# HG changeset patch # User cannam # Date 1200938567 0 # Node ID 499d438b52ba5752c3832fa25031e1e478820d76 # Parent 8bb764969d50293ad50cebf74d1572edb333df4e * Add KL divergence of histograms diff -r 8bb764969d50 -r 499d438b52ba maths/KLDivergence.cpp --- a/maths/KLDivergence.cpp Fri Jan 18 17:57:40 2008 +0000 +++ b/maths/KLDivergence.cpp Mon Jan 21 18:02:47 2008 +0000 @@ -10,10 +10,12 @@ #include "KLDivergence.h" -double KLDivergence::distance(const vector &m1, - const vector &v1, - const vector &m2, - const vector &v2) +#include + +double KLDivergence::distanceGaussian(const vector &m1, + const vector &v1, + const vector &m2, + const vector &v2) { int sz = m1.size(); @@ -28,3 +30,24 @@ return d; } + +double KLDivergence::distanceDistribution(const vector &d1, + const vector &d2, + bool symmetrised) +{ + int sz = d1.size(); + + double d = 0; + double small = 1e-20; + + for (int i = 0; i < sz; ++i) { + d += d1[i] * log10((d1[i] + small) / (d2[i] + small)); + } + + if (symmetrised) { + d += distanceDistribution(d2, d1, false); + } + + return d; +} + diff -r 8bb764969d50 -r 499d438b52ba maths/KLDivergence.h --- a/maths/KLDivergence.h Fri Jan 18 17:57:40 2008 +0000 +++ b/maths/KLDivergence.h Mon Jan 21 18:02:47 2008 +0000 @@ -4,7 +4,7 @@ QM DSP Library Centre for Digital Music, Queen Mary, University of London. - This file copyright 2008 QMUL + This file copyright 2008 QMUL. All rights reserved. */ @@ -16,21 +16,33 @@ using std::vector; /** - * Calculate a symmetrised Kullback-Leibler divergence of Gaussian - * models based on mean and variance vectors. All input vectors must - * be of equal size. + * Helper methods for calculating Kullback-Leibler divergences. */ - class KLDivergence { public: KLDivergence() { } ~KLDivergence() { } - double distance(const vector &means1, - const vector &variances1, - const vector &means2, - const vector &variances2); + /** + * Calculate a symmetrised Kullback-Leibler divergence of Gaussian + * models based on mean and variance vectors. All input vectors + * must be of equal size. + */ + double distanceGaussian(const vector &means1, + const vector &variances1, + const vector &means2, + const vector &variances2); + + /** + * Calculate a Kullback-Leibler divergence of two probability + * distributions. Input vectors must be of equal size. If + * symmetrised is true, the result will be the symmetrised + * distance (equal to KL(d1, d2) + KL(d2, d1)). + */ + double distanceDistribution(const vector &d1, + const vector &d2, + bool symmetrised); }; #endif