Engauge Digitizer  2
TestCorrelation.cpp
1 #include "Correlation.h"
2 #include "Logger.h"
3 #include "MainWindow.h"
4 #include <qmath.h>
5 #include <QStringList>
6 #include <QtTest/QtTest>
7 #include "Test/TestCorrelation.h"
8 
9 QTEST_MAIN (TestCorrelation)
10 
11 TestCorrelation::TestCorrelation(QObject *parent) :
12  QObject(parent)
13 {
14 }
15 
16 void TestCorrelation::cleanupTestCase ()
17 {
18 }
19 
20 void TestCorrelation::initTestCase ()
21 {
22  const QString NO_ERROR_REPORT_LOG_FILE;
23  const QString NO_REGRESSION_OPEN_FILE;
24  const bool NO_GNUPLOT_LOG_FILES = false;
25  const bool NO_REGRESSION_IMPORT = false;
26  const bool NO_RESET = false;
27  const bool DEBUG_FLAG = false;
28  const QStringList NO_LOAD_STARTUP_FILES;
29 
30  initializeLogging ("engauge_test",
31  "engauge_test.log",
32  DEBUG_FLAG);
33 
34  MainWindow w (NO_ERROR_REPORT_LOG_FILE,
35  NO_REGRESSION_OPEN_FILE,
36  NO_GNUPLOT_LOG_FILES,
37  NO_RESET,
38  NO_REGRESSION_IMPORT,
39  NO_LOAD_STARTUP_FILES);
40  w.show ();
41 }
42 
43 void TestCorrelation::loadSinusoid (double function [],
44  int n,
45  int center) const
46 {
47  for (int i = 0; i < n; i++) {
48  int x = i - center;
49  if (x == 0) {
50  function [i] = 1.0;
51  } else {
52  function [i] = qSin (x) / x;
53  }
54  }
55 }
56 
57 void TestCorrelation::loadThreeTriangles (double function [],
58  int n,
59  int center) const
60 {
61  const int PEAK_SEPARATION = 50, PEAK_HALF_WIDTH = 5;
62 
63  int x;
64  for (int i = 0; i < n; i++) {
65 
66  // First try for peak at center
67  x = i - center;
68  if (x > PEAK_HALF_WIDTH) {
69 
70  // Failed, so try again for peak at center-separation
71  x = i - (center - PEAK_SEPARATION);
72  if (x > PEAK_HALF_WIDTH) {
73 
74  // Failed, so try again for peak at center+separation
75  x = i - (center + PEAK_SEPARATION);
76  }
77  }
78 
79  if (x < PEAK_HALF_WIDTH) {
80 
81  // Map 0<x<PEAK_HALF_WIDTH to 1<function<0
82  function [i] = (double) (PEAK_HALF_WIDTH - x) / (double) PEAK_HALF_WIDTH;
83 
84  } else {
85 
86  function [i] = 0;
87  }
88  }
89 }
90 
91 void TestCorrelation::testShiftSinusoidNonPowerOf2 ()
92 {
93  const int N = 1000; // Non power of 2
94  const int INDEX_MAX = 200, INDEX_SHIFT = 50;
95 
96  int binStartMax;
97  double function1 [N], function2 [N], correlations [N];
98  double corrMax;
99 
100  Correlation correlation (N);
101 
102  // Function1 peak is at INDEX_MAX
103  // Function2 peak is at INDEX_MAX + INDEX_SHIFT
104  loadSinusoid (function1, N, INDEX_MAX);
105  loadSinusoid (function2, N, INDEX_MAX + INDEX_SHIFT);
106 
107  correlation.correlateWithShift (N,
108  function1,
109  function2,
110  binStartMax,
111  corrMax,
112  correlations);
113 
114  QVERIFY ((binStartMax = INDEX_SHIFT));
115 }
116 
117 void TestCorrelation::testShiftSinusoidPowerOf2 ()
118 {
119  const int N = 1024; // Power of 2
120  const int INDEX_MAX = 200, INDEX_SHIFT = 50;
121 
122  int binStartMax;
123  double function1 [N], function2 [N], correlations [N];
124  double corrMax;
125 
126  Correlation correlation (N);
127 
128  // Function1 peak is at INDEX_MAX
129  // Function2 peak is at INDEX_MAX + INDEX_SHIFT
130  loadSinusoid (function1, N, INDEX_MAX);
131  loadSinusoid (function2, N, INDEX_MAX + INDEX_SHIFT);
132 
133  correlation.correlateWithShift (N,
134  function1,
135  function2,
136  binStartMax,
137  corrMax,
138  correlations);
139 
140  QVERIFY ((binStartMax = INDEX_SHIFT));
141 }
142 
143 void TestCorrelation::testShiftThreeTrianglesNonPowerOf2 ()
144 {
145  const int N = 1000; // Non power of 2
146  const int INDEX_MAX = 200, INDEX_SHIFT = 50;
147 
148  int binStartMax;
149  double function1 [N], function2 [N], correlations [N];
150  double corrMax;
151 
152  Correlation correlation (N);
153 
154  // Function1 peak is at INDEX_MAX
155  // Function2 peak is at INDEX_MAX + INDEX_SHIFT
156  loadThreeTriangles (function1, N, INDEX_MAX);
157  loadThreeTriangles (function2, N, INDEX_MAX + INDEX_SHIFT);
158 
159  correlation.correlateWithShift (N,
160  function1,
161  function2,
162  binStartMax,
163  corrMax,
164  correlations);
165 
166  QVERIFY ((binStartMax = INDEX_SHIFT));
167 }
168 
169 void TestCorrelation::testShiftThreeTrianglesPowerOf2 ()
170 {
171  const int N = 1024; // Power of 2
172  const int INDEX_MAX = 200, INDEX_SHIFT = 50;
173 
174  int binStartMax;
175  double function1 [N], function2 [N], correlations [N];
176  double corrMax;
177 
178  Correlation correlation (N);
179 
180  // Function1 peak is at INDEX_MAX
181  // Function2 peak is at INDEX_MAX + INDEX_SHIFT
182  loadThreeTriangles (function1, N, INDEX_MAX);
183  loadThreeTriangles (function2, N, INDEX_MAX + INDEX_SHIFT);
184 
185  correlation.correlateWithShift (N,
186  function1,
187  function2,
188  binStartMax,
189  corrMax,
190  correlations);
191 
192  QVERIFY ((binStartMax = INDEX_SHIFT));
193 }
Fast cross correlation between two functions.
Definition: Correlation.h:14
Unit tests of fast correlation algorithm.
void correlateWithShift(int N, const double function1 [], const double function2 [], int &binStartMax, double &corrMax, double correlations []) const
Return the shift in function1 that best aligns that function with function2.
Definition: Correlation.cpp:44
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:89