changeset 1394:9ef1cc26024c

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).
author Chris Cannam
date Tue, 28 Feb 2017 14:04:16 +0000
parents 04abe8f73b22
children 7e3532d56abb
files base/ColumnOp.cpp base/ColumnOp.h base/test/TestColumnOp.h
diffstat 3 files changed, 55 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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);
--- 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 };