LogRange.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2006 Chris Cannam.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #include "LogRange.h"
17 #include "system/System.h"
18 
19 #include <algorithm>
20 #include <iostream>
21 #include <cmath>
22 
23 void
24 LogRange::mapRange(double &min, double &max, double logthresh)
25 {
26  static double eps = 1e-10;
27 
28  // ensure that max > min:
29  if (min > max) std::swap(min, max);
30  if (max == min) max = min + 1;
31 
32  if (min >= 0.0) {
33 
34  // and max > min, so we know min >= 0 and max > 0
35 
36  max = log10(max);
37 
38  if (min == 0.0) min = std::min(logthresh, max);
39  else min = log10(min);
40 
41  } else if (max <= 0.0) {
42 
43  // and max > min, so we know min < 0 and max <= 0
44 
45  min = log10(-min);
46 
47  if (max == 0.0) max = std::min(logthresh, min);
48  else max = log10(-max);
49 
50  std::swap(min, max);
51 
52  } else {
53 
54  // min < 0 and max > 0
55 
56  max = log10(std::max(max, -min));
57  min = std::min(logthresh, max);
58  }
59 
60  if (fabs(max - min) < eps) min = max - 1;
61 }
62 
63 double
64 LogRange::map(double value, double thresh)
65 {
66  if (value == 0.0) return thresh;
67  return log10(fabs(value));
68 }
69 
70 double
71 LogRange::unmap(double value)
72 {
73  return pow(10.0, value);
74 }
75 
76 static double
77 sd(const std::vector<double> &values, int start, int n)
78 {
79  double sum = 0.0, mean = 0.0, variance = 0.0;
80  for (int i = 0; i < n; ++i) {
81  sum += values[start + i];
82  }
83  mean = sum / n;
84  for (int i = 0; i < n; ++i) {
85  double diff = values[start + i] - mean;
86  variance += diff * diff;
87  }
88  variance = variance / n;
89  return sqrt(variance);
90 }
91 
92 bool
93 LogRange::shouldUseLogScale(std::vector<double> values)
94 {
95  // Principle: Partition the data into two sets around the median;
96  // calculate the standard deviation of each set; if the two SDs
97  // are very different, it's likely that a log scale would be good.
98 
99  int n = int(values.size());
100  if (n < 4) return false;
101  std::sort(values.begin(), values.end());
102  int mi = n / 2;
103 
104  double sd0 = sd(values, 0, mi);
105  double sd1 = sd(values, mi, n - mi);
106 
107  SVDEBUG << "LogRange::useLogScale: sd0 = "
108  << sd0 << ", sd1 = " << sd1 << endl;
109 
110  if (sd0 == 0 || sd1 == 0) return false;
111 
112  // I wonder what method of determining "one sd much bigger than
113  // the other" would be appropriate here...
114  if (std::max(sd0, sd1) / std::min(sd0, sd1) > 10.) return true;
115  else return false;
116 }
117 
static void mapRange(double &min, double &max, double thresh=-10)
Map a linear range onto a logarithmic range.
Definition: LogRange.cpp:24
static double unmap(double value)
Map a value from the logarithmic range back again.
Definition: LogRange.cpp:71
static double map(double value, double thresh=-10)
Map a value onto a logarithmic range.
Definition: LogRange.cpp:64
static double sd(const std::vector< double > &values, int start, int n)
Definition: LogRange.cpp:77
static bool shouldUseLogScale(std::vector< double > values)
Estimate whether a set of values would be more properly shown using a logarithmic than a linear scale...
Definition: LogRange.cpp:93
#define SVDEBUG
Definition: Debug.h:106