# HG changeset patch # User Chris Cannam # Date 1488290656 0 # Node ID 9ef1cc26024c8e4bb317769106e6627dbf92b769 # Parent 04abe8f73b22362fb8ecdb8137d77e17993f1c75 Add Range01 normalisation method to ColumnOp. This is the normalisation that is actually used in the Colour 3D Plot layer historically when column normalisation is enabled (not Max1 after all). diff -r 04abe8f73b22 -r 9ef1cc26024c base/ColumnOp.cpp --- a/base/ColumnOp.cpp Tue Feb 28 11:26:24 2017 +0000 +++ b/base/ColumnOp.cpp Tue Feb 28 14:04:16 2017 +0000 @@ -49,10 +49,33 @@ if (n == ColumnNormalization::None || in.empty()) { return in; } + + float shift = 0.f; + float scale = 1.f; - float scale = 1.f; - - if (n == ColumnNormalization::Sum1) { + if (n == ColumnNormalization::Range01) { + + float min = 0.f; + float max = 0.f; + bool have = false; + for (auto v: in) { + if (v < min || !have) { + min = v; + } + if (v > max || !have) { + max = v; + } + have = true; + } + if (min != 0.f) { + shift = -min; + max -= min; + } + if (max != 0.f) { + scale = 1.f / max; + } + + } else if (n == ColumnNormalization::Sum1) { float sum = 0.f; @@ -86,7 +109,7 @@ } } - return applyGain(in, scale); + return applyGain(applyShift(in, shift), scale); } ColumnOp::Column diff -r 04abe8f73b22 -r 9ef1cc26024c base/ColumnOp.h --- a/base/ColumnOp.h Tue Feb 28 11:26:24 2017 +0000 +++ b/base/ColumnOp.h Tue Feb 28 14:04:16 2017 +0000 @@ -26,6 +26,9 @@ * Max1 means to normalize to max value = 1.0. * Sum1 means to normalize to sum of values = 1.0. * + * Range01 means to normalize such that the max value = 1.0 and the + * min value (if different from the max value) = 0.0. + * * Hybrid means normalize to max = 1.0 and then multiply by * log10 of the max value, to retain some difference between * levels of neighbouring columns. @@ -36,6 +39,7 @@ None, Max1, Sum1, + Range01, Hybrid }; @@ -63,6 +67,17 @@ } /** + * Shift the values in the given column by the given offset. + */ + static Column applyShift(const Column &in, float offset) { + if (offset == 0.f) return in; + Column out; + out.reserve(in.size()); + for (auto v: in) out.push_back(v + offset); + return out; + } + + /** * Scale an FFT output downward by half the FFT size. */ static Column fftScale(const Column &in, int fftSize); diff -r 04abe8f73b22 -r 9ef1cc26024c base/test/TestColumnOp.h --- a/base/test/TestColumnOp.h Tue Feb 28 11:26:24 2017 +0000 +++ b/base/test/TestColumnOp.h Tue Feb 28 14:04:16 2017 +0000 @@ -139,6 +139,7 @@ QCOMPARE(C::normalize({}, ColumnNormalization::None), Column()); QCOMPARE(C::normalize({}, ColumnNormalization::Sum1), Column()); QCOMPARE(C::normalize({}, ColumnNormalization::Max1), Column()); + QCOMPARE(C::normalize({}, ColumnNormalization::Range01), Column()); QCOMPARE(C::normalize({}, ColumnNormalization::Hybrid), Column()); } @@ -176,6 +177,18 @@ Column({ -1.0f, -0.75f, 0.5f, 0.25f })); } + void normalize_range01() { + Column c { 4, 3, 2, 1 }; + QCOMPARE(C::normalize(c, ColumnNormalization::Range01), + Column({ 1.0f, 2.f/3.f, 1.f/3.f, 0.0f })); + } + + void normalize_range01_mixedSign() { + Column c { -2, -3, 2, 1 }; + QCOMPARE(C::normalize(c, ColumnNormalization::Range01), + Column({ 0.2f, 0.0f, 1.0f, 0.8f })); + } + void normalize_hybrid() { // with max == 99, log10(max+1) == 2 so scale factor will be 2/99 Column c { 22, 44, 99, 66 };