changeset 21:51d6dd470646

Normalisation code
author Chris Cannam
date Mon, 28 Sep 2015 14:51:17 +0100
parents 3bbdd3dada9f
children 528185bfb0e9
files Makefile.inc src/Normalise.cpp src/Normalise.h src/test-normalise.cpp
diffstat 4 files changed, 119 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.inc	Thu Sep 24 16:36:39 2015 +0100
+++ b/Makefile.inc	Mon Sep 28 14:51:17 2015 +0100
@@ -24,8 +24,8 @@
 
 PUBLIC_HEADERS	:=
 
-LIB_HEADERS	:= $(SRC_DIR)/delays.h $(SRC_DIR)/filter-a.h $(SRC_DIR)/filter-b.h $(SRC_DIR)/Filter.h $(SRC_DIR)/PitchFilterbank.h $(SRC_DIR)/DCT.h $(SRC_DIR)/Types.h $(SRC_DIR)/CRP.h
-LIB_SOURCES	:= $(SRC_DIR)/Filter.cpp $(SRC_DIR)/PitchFilterbank.cpp $(SRC_DIR)/DCT.cpp $(SRC_DIR)/CRP.cpp
+LIB_HEADERS	:= $(SRC_DIR)/delays.h $(SRC_DIR)/filter-a.h $(SRC_DIR)/filter-b.h $(SRC_DIR)/Filter.h $(SRC_DIR)/PitchFilterbank.h $(SRC_DIR)/DCT.h $(SRC_DIR)/Types.h $(SRC_DIR)/CRP.h $(SRC_DIR)/Normalise.h
+LIB_SOURCES	:= $(SRC_DIR)/Filter.cpp $(SRC_DIR)/PitchFilterbank.cpp $(SRC_DIR)/DCT.cpp $(SRC_DIR)/CRP.cpp $(SRC_DIR)/Normalise.cpp
 LIB_OBJECTS	:= $(LIB_SOURCES:.cpp=.o)
 LIB_OBJECTS	:= $(LIB_OBJECTS:.c=.o)
 
@@ -39,7 +39,7 @@
 BQVEC_OBJECTS	:= $(BQVEC_SOURCES:.cpp=.o)
 BQVEC_OBJECTS	:= $(BQVEC_OBJECTS:.c=.o)
 
-TEST_SOURCES	:= $(SRC_DIR)/test-filter.cpp $(SRC_DIR)/test-dct.cpp
+TEST_SOURCES	:= $(SRC_DIR)/test-filter.cpp $(SRC_DIR)/test-dct.cpp $(SRC_DIR)/test-normalise.cpp
 TEST_OBJECTS	:= $(TEST_SOURCES:.cpp=.o)
 TEST_OBJECTS	:= $(TEST_OBJECTS:.c=.o)
 
@@ -67,9 +67,10 @@
 	$(RANLIB) $@
 
 .PHONY:	tests
-tests:	test-dct test-filter
+tests:	test-dct test-filter test-normalise
 	./test-dct
 	./test-filter
+	./test-normalise
 
 test-dct:	  $(TEST_OBJECTS) $(LIBRARY)
 	$(CXX) -o $@ src/test-dct.o $(LIBRARY)
@@ -77,6 +78,9 @@
 test-filter:	  $(TEST_OBJECTS) $(LIBRARY)
 	$(CXX) -o $@ src/test-filter.o $(LIBRARY)
 
+test-normalise:	  $(TEST_OBJECTS) $(LIBRARY)
+	$(CXX) -o $@ src/test-normalise.o $(LIBRARY)
+
 clean:		
 	rm -f $(OBJECTS)
 	$(MAKE) -C constant-q-cpp -f Makefile$(MAKEFILE_EXT) clean
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Normalise.cpp	Mon Sep 28 14:51:17 2015 +0100
@@ -0,0 +1,29 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+#include "Normalise.h"
+
+#include <cmath>
+
+using namespace std;
+
+double
+Normalise::norm(vector<double> v, int p)
+{
+    double tot = 0.0;
+    for (auto x: v) tot += abs(pow(x, p));
+    return pow(tot, 1.0 / p);
+}
+
+vector<double>
+Normalise::normalise(vector<double> v, int p, double threshold)
+{
+    int n = v.size();
+    double nv = norm(v, p);
+    if (nv < threshold) {
+	return vector<double>(n, 1.0 / pow(n, 1.0 / p)); // unit vector
+    }
+    vector<double> out;
+    for (auto x: v) out.push_back(x / nv);
+    return out;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Normalise.h	Mon Sep 28 14:51:17 2015 +0100
@@ -0,0 +1,19 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+#ifndef NORMALISE_H
+#define NORMALISE_H
+
+#include <vector>
+
+class Normalise
+{
+public:
+    static double norm(std::vector<double> v,
+		       int p = 2); // L^p norm
+
+    static std::vector<double> normalise(std::vector<double> v,
+					 int p = 2,
+					 double threshold = 1e-6);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test-normalise.cpp	Mon Sep 28 14:51:17 2015 +0100
@@ -0,0 +1,63 @@
+
+#include "Normalise.h"
+
+#include <iostream>
+#include <cmath>
+
+using namespace std;
+
+void check(string context, vector<double> got, vector<double> expected, bool &good)
+{
+    double thresh = 1e-4;
+    for (int i = 0; i < int(got.size()); ++i) {
+	if (fabs(got[i] - expected[i]) > thresh) {
+	    cerr << "ERROR: " << context << "[" << i << "] (" << got[i]
+		 << ") differs from expected " << expected[i] << endl;
+	    good = false;
+	}
+    }
+}
+
+int main(int argc, char **argv)
+{
+    bool good = true;
+    
+    vector<double> in { -1, 1.5, 3, 5 };
+
+    vector<double> out, expected;
+
+    out = Normalise::normalise(in, 1);
+    expected = { -0.095238, 0.142857, 0.285714, 0.476190 };
+    check("L1", out, expected, good);
+    
+    out = Normalise::normalise(in, 2);
+    expected = { -0.16385, 0.24577, 0.49154, 0.81923 };
+    check("L2", out, expected, good);
+    
+    out = Normalise::normalise(in, 3);
+    expected = { -0.18561, 0.27842, 0.55684, 0.92807 };
+    check("L3", out, expected, good);
+
+    in = { 0, 0, 0, 0 };
+
+    out = Normalise::normalise(in, 1);
+    expected = { 0.25, 0.25, 0.25, 0.25 };
+    check("L1_zero", out, expected, good);
+    
+    out = Normalise::normalise(in, 2);
+    expected = { 0.5, 0.5, 0.5, 0.5 };
+    check("L2_zero", out, expected, good);
+    
+    out = Normalise::normalise(in, 3);
+    expected = { 0.62996, 0.62996, 0.62996, 0.62996 };
+    check("L3_zero", out, expected, good);
+
+    if (good) {
+	cerr << "Success" << endl;
+	return 0;
+    } else {
+	return 1;
+    }
+}
+
+