changeset 33:499d438b52ba

* Add KL divergence of histograms
author cannam
date Mon, 21 Jan 2008 18:02:47 +0000
parents 8bb764969d50
children ad645e404d0c
files maths/KLDivergence.cpp maths/KLDivergence.h
diffstat 2 files changed, 48 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- 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<double> &m1,
-			      const vector<double> &v1,
-			      const vector<double> &m2,
-			      const vector<double> &v2)
+#include <cmath>
+
+double KLDivergence::distanceGaussian(const vector<double> &m1,
+                                      const vector<double> &v1,
+                                      const vector<double> &m2,
+                                      const vector<double> &v2)
 {
     int sz = m1.size();
 
@@ -28,3 +30,24 @@
 
     return d;
 }
+
+double KLDivergence::distanceDistribution(const vector<double> &d1,
+                                          const vector<double> &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;
+}
+
--- 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<double> &means1,
-		    const vector<double> &variances1,
-		    const vector<double> &means2,
-		    const vector<double> &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<double> &means1,
+                            const vector<double> &variances1,
+                            const vector<double> &means2,
+                            const vector<double> &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<double> &d1,
+                                const vector<double> &d2,
+                                bool symmetrised);
 };
 
 #endif