Mercurial > hg > tipic
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; + } +} + +