1 #include "vtkAbstractArray.h"
2 #include "vtkDoubleArray.h"
3 #include "vtkIntArray.h"
4 #include "vtkNew.h"
5 #include "vtkStringArray.h"
6 #include "vtkVariantArray.h"
7
8 static double testTuplesDouble[] = {
9 // A simple test where every component *and* the
10 // tuples as a whole behave discretely.
11 0., 0., 1.,
12 1., 0., 3.,
13 0., 2., 7.,
14 0., 0., 9.,
15 1., 0., 1.,
16 0., 2., 8.,
17 };
18 // Bounds on the number of unique values that should be identified.
19 // For larger data, the number may not be precise
20 // as we sample subsets of the data.
21 static int numUniqueDouble[] = {
22 2, 2,
23 2, 2,
24 5, 5,
25 6, 6,
26 };
27
28 static int testTuplesInt[] = {
29 /*
30 These next tuples repeat 16 coordinate values but are frequently not
31 identical in both components to other tuples. Thus the components
32 should have 16 discrete values reported, but the vectors as
33 a whole should not since there are 43 distinct tuples.
34 Furthermore, the array is sampled as opposed to exhastively enumerated
35 and so only 15 unique values are detected for component 1.
36 */
37 16, 1,
38 8, 14,
39 10, 3,
40 11, 4,
41 2, 13,
42 7, 12,
43 6, 5,
44 15, 9,
45 15, 6,
46 9, 7,
47 11, 16,
48 1, 5,
49 2, 3,
50 13, 12,
51 4, 8,
52 14, 10,
53 4, 14,
54 11, 9,
55 7, 3,
56 8, 2,
57 12, 13,
58 1, 6,
59 15, 10,
60 16, 5,
61 4, 10,
62 12, 3,
63 5, 8,
64 13, 1,
65 14, 11,
66 2, 6,
67 15, 9,
68 7, 16,
69 1, 2,
70 5, 3,
71 16, 13,
72 15, 9,
73 11, 12,
74 7, 14,
75 8, 10,
76 4, 6,
77 8, 13,
78 16, 14,
79 15, 2,
80 11, 1,
81 3, 10,
82 4, 6,
83 7, 12,
84 5, 9,
85 };
86 static int numUniqueInt[] = {
87 1, 16,
88 1, 16,
89 0, 0,
90 };
91
92 static int testTuplesInt2[] = {
93 // There are no repeats in this set.
94 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
95 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
96 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
97 31, 32, 33,
98 };
99 static int numUniqueInt2[] = {
100 0, 0,
101 };
102
103 static vtkStdString testTuplesString[] = {
104 /*
105 To test the log(N) sampling strategy, we must
106 have a large number of entries in the array.
107
108 The 4 words marked "not detected" below are placed to leave them
109 intentionally undetected on at least one platform.
110 The vtkObject ModificationTime counter is used as a
111 seed for the random number generator and its count
112 will vary across platforms and compile-time options,
113 so we accept anywhere from 4 to 8 values being detected
114 when subsampling. This data is used twice: once forcing all
115 tuples to be sampled and once using subsampling.
116 */
117 "Eeny", "Meeny", "Miny", "Mo", "Miny",
118 "Eeny", "Meeny", "Miny", "Mo", "Miny",
119 "Eeny", "Meeny", "Miny", "Mo", "Miny",
120 "Eeny", "Meeny", "Miny", "Mo", "Miny",
121 "Skeenie", "Beeny", "Piny", "Po", "Po", // not detected.
122 "Eeny", "Meeny", "Miny", "Mo", "Miny",
123 "Eeny", "Meeny", "Miny", "Mo", "Miny",
124 "Eeny", "Meeny", "Miny", "Mo", "Miny",
125 "Eeny", "Meeny", "Miny", "Mo", "Miny",
126 "Eeny", "Meeny", "Miny", "Mo", "Miny",
127 "Eeny", "Meeny", "Miny", "Mo", "Miny",
128 "Eeny", "Meeny", "Miny", "Mo", "Miny",
129 "Eeny", "Meeny", "Miny", "Mo", "Miny",
130 "Eeny", "Meeny", "Miny", "Mo", "Miny",
131 "Eeny", "Meeny", "Miny", "Mo", "Miny",
132 "Eeny", "Meeny", "Miny", "Mo", "Miny",
133 "Eeny", "Meeny", "Miny", "Mo", "Miny",
134 "Eeny", "Meeny", "Miny", "Mo", "Miny",
135 "Eeny", "Meeny", "Miny", "Mo", "Miny",
136 "Eeny", "Meeny", "Miny", "Mo", "Miny",
137 "Eeny", "Meeny", "Miny", "Mo", "Miny",
138 "Eeny", "Meeny", "Miny", "Mo", "Miny",
139 "Eeny", "Meeny", "Miny", "Mo", "Miny",
140 "Eeny", "Meeny", "Miny", "Mo", "Miny",
141 "Eeny", "Meeny", "Miny", "Mo", "Miny",
142 "Eeny", "Meeny", "Miny", "Mo", "Miny",
143 "Eeny", "Meeny", "Miny", "Mo", "Miny",
144 "Eeny", "Meeny", "Miny", "Mo", "Miny",
145 "Eeny", "Meeny", "Miny", "Mo", "Miny",
146 "Eeny", "Meeny", "Miny", "Mo", "Miny",
147 "Eeny", "Meeny", "Miny", "Mo", "Miny",
148 "Eeny", "Meeny", "Miny", "Mo", "Miny",
149 "Eeny", "Meeny", "Miny", "Mo", "Miny",
150 "Eeny", "Meeny", "Miny", "Mo", "Miny",
151 "Eeny", "Meeny", "Miny", "Mo", "Miny",
152 "Eeny", "Meeny", "Miny", "Mo", "Miny",
153 "Eeny", "Meeny", "Miny", "Mo", "Miny",
154 "Eeny", "Meeny", "Miny", "Mo", "Miny",
155 "Eeny", "Meeny", "Miny", "Mo", "Miny",
156 "Eeny", "Meeny", "Miny", "Mo", "Miny",
157 "Eeny", "Meeny", "Miny", "Mo", "Miny",
158 "Eeny", "Meeny", "Miny", "Mo", "Miny",
159 "Eeny", "Meeny", "Miny", "Mo", "Miny",
160 "Eeny", "Meeny", "Miny", "Mo", "Miny",
161 "Eeny", "Meeny", "Miny", "Mo", "Miny",
162 "Eeny", "Meeny", "Miny", "Mo", "Miny",
163 "Eeny", "Meeny", "Miny", "Mo", "Miny",
164 "Eeny", "Meeny", "Miny", "Mo", "Miny",
165 "Eeny", "Meeny", "Miny", "Mo", "Miny",
166 "Eeny", "Meeny", "Miny", "Mo", "Miny",
167 "Eeny", "Meeny", "Miny", "Mo", "Miny",
168 "Eeny", "Meeny", "Miny", "Mo", "Miny",
169 "Eeny", "Meeny", "Miny", "Mo", "Miny",
170 "Eeny", "Meeny", "Miny", "Mo", "Miny",
171 "Eeny", "Meeny", "Miny", "Mo", "Miny",
172 "Eeny", "Meeny", "Miny", "Mo", "Miny",
173 "Eeny", "Meeny", "Miny", "Mo", "Miny",
174 "Eeny", "Meeny", "Miny", "Mo", "Miny",
175 "Eeny", "Meeny", "Miny", "Mo", "Miny",
176 "Eeny", "Meeny", "Miny", "Mo", "Miny",
177 "Eeny", "Meeny", "Miny", "Mo", "Miny",
178 "Eeny", "Meeny", "Miny", "Mo", "Miny",
179 "Eeny", "Meeny", "Miny", "Mo", "Miny",
180 "Eeny", "Meeny", "Miny", "Mo", "Miny",
181 "Eeny", "Meeny", "Miny", "Mo", "Miny",
182 "Eeny", "Meeny", "Miny", "Mo", "Miny",
183 "Eeny", "Meeny", "Miny", "Mo", "Miny",
184 "Eeny", "Meeny", "Miny", "Mo", "Miny",
185 "Eeny", "Meeny", "Miny", "Mo", "Miny",
186 "Eeny", "Meeny", "Miny", "Mo", "Miny",
187 "Eeny", "Meeny", "Miny", "Mo", "Miny",
188 "Eeny", "Meeny", "Miny", "Mo", "Miny",
189 "Eeny", "Meeny", "Miny", "Mo", "Miny",
190 "Eeny", "Meeny", "Miny", "Mo", "Miny",
191 "Eeny", "Meeny", "Miny", "Mo", "Miny",
192 "Eeny", "Meeny", "Miny", "Mo", "Miny",
193 "Eeny", "Meeny", "Miny", "Mo", "Miny",
194 "Eeny", "Meeny", "Miny", "Mo", "Miny",
195 "Eeny", "Meeny", "Miny", "Mo", "Miny",
196 "Eeny", "Meeny", "Miny", "Mo", "Miny",
197 "Eeny", "Meeny", "Miny", "Mo", "Miny",
198 "Eeny", "Meeny", "Miny", "Mo", "Miny",
199 "Eeny", "Meeny", "Miny", "Mo", "Miny",
200 "Eeny", "Meeny", "Miny", "Mo", "Miny",
201 "Eeny", "Meeny", "Miny", "Mo", "Miny",
202 "Eeny", "Meeny", "Miny", "Mo", "Miny",
203 "Eeny", "Meeny", "Miny", "Mo", "Miny",
204 "Eeny", "Meeny", "Miny", "Mo", "Miny",
205 "Eeny", "Meeny", "Miny", "Mo", "Miny",
206 "Eeny", "Meeny", "Miny", "Mo", "Miny",
207 "Eeny", "Meeny", "Miny", "Mo", "Miny",
208 "Eeny", "Meeny", "Miny", "Mo", "Miny",
209 "Eeny", "Meeny", "Miny", "Mo", "Miny",
210 "Eeny", "Meeny", "Miny", "Mo", "Miny",
211 "Eeny", "Meeny", "Miny", "Mo", "Miny",
212 "Eeny", "Meeny", "Miny", "Mo", "Miny",
213 "Eeny", "Meeny", "Miny", "Mo", "Miny",
214 "Eeny", "Meeny", "Miny", "Mo", "Miny",
215 "Eeny", "Meeny", "Miny", "Mo", "Miny",
216 "Eeny", "Meeny", "Miny", "Mo", "Miny",
217 "Eeny", "Meeny", "Miny", "Mo", "Miny",
218 "Eeny", "Meeny", "Miny", "Mo", "Miny",
219 "Eeny", "Meeny", "Miny", "Mo", "Miny",
220 "Eeny", "Meeny", "Miny", "Mo", "Miny",
221 "Eeny", "Meeny", "Miny", "Mo", "Miny",
222 "Eeny", "Meeny", "Miny", "Mo", "Miny",
223 "Eeny", "Meeny", "Miny", "Mo", "Miny",
224 "Eeny", "Meeny", "Miny", "Mo", "Miny",
225 "Eeny", "Meeny", "Miny", "Mo", "Miny",
226 "Eeny", "Meeny", "Miny", "Mo", "Miny",
227 "Eeny", "Meeny", "Miny", "Mo", "Miny",
228 "Eeny", "Meeny", "Miny", "Mo", "Miny",
229 "Eeny", "Meeny", "Miny", "Mo", "Miny",
230 "Eeny", "Meeny", "Miny", "Mo", "Miny",
231 "Eeny", "Meeny", "Miny", "Mo", "Miny",
232 "Eeny", "Meeny", "Miny", "Mo", "Miny",
233 "Eeny", "Meeny", "Miny", "Mo", "Miny",
234 "Eeny", "Meeny", "Miny", "Mo", "Miny",
235 "Eeny", "Meeny", "Miny", "Mo", "Miny",
236 "Eeny", "Meeny", "Miny", "Mo", "Miny",
237 "Eeny", "Meeny", "Miny", "Mo", "Miny",
238 "Eeny", "Meeny", "Miny", "Mo", "Miny",
239 "Eeny", "Meeny", "Miny", "Mo", "Miny",
240 "Eeny", "Meeny", "Miny", "Mo", "Miny",
241 "Eeny", "Meeny", "Miny", "Mo", "Miny",
242 "Eeny", "Meeny", "Miny", "Mo", "Miny",
243 "Eeny", "Meeny", "Miny", "Mo", "Miny",
244 "Eeny", "Meeny", "Miny", "Mo", "Miny",
245 "Eeny", "Meeny", "Miny", "Mo", "Miny",
246 };
247 static int numUniqueStringComplete[2] = {
248 8, 8,
249 };
250 static int numUniqueStringSubset[2] = {
251 4, 8,
252 };
253
CheckUniques(vtkAbstractArray * arr,int * uniqueSizeBds,double uncertainty,double minProminence)254 static bool CheckUniques(
255 vtkAbstractArray* arr, int* uniqueSizeBds,
256 double uncertainty, double minProminence)
257 {
258 bool ok = true;
259 if (!arr)
260 {
261 return ok;
262 }
263
264 cout << arr->GetName() << endl;
265
266 int nc = arr->GetNumberOfComponents();
267 vtkNew<vtkVariantArray> uniques;
268 for (int c = 0; c < nc; ++c)
269 {
270 arr->GetProminentComponentValues(
271 c, uniques.GetPointer(), uncertainty, minProminence);
272 int numUniques = static_cast<int>(uniques->GetNumberOfTuples());
273 cout << " comp " << c << " (" << numUniques << "): ";
274 for (int n = 0; n <= uniques->GetMaxId(); ++n)
275 {
276 cout
277 << (n > 0 ? ", " : " ")
278 << uniques->GetVariantValue(n).ToString().c_str();
279 }
280 cout << endl;
281 if (
282 uniqueSizeBds[2 * c] > numUniques ||
283 uniqueSizeBds[2 * c + 1] < numUniques)
284 {
285 cout
286 << " ** ERROR: Expected between " << uniqueSizeBds[2 * c]
287 << " and " << uniqueSizeBds[2 * c + 1] << " values\n";
288 ok = false;
289 }
290 }
291 if (nc > 1)
292 {
293 arr->GetProminentComponentValues(
294 -1, uniques.GetPointer(), uncertainty, minProminence);
295 int numUniques = static_cast<int>(uniques->GetNumberOfTuples());
296 cout << " tuples (" << numUniques << "): ";
297 for (int n = 0; n <= uniques->GetMaxId(); ++n)
298 {
299 cout
300 << (n > 0 && n % nc == 0 ? ", " : " ")
301 << uniques->GetVariantValue(n).ToString().c_str();
302 }
303 cout << endl;
304 if (
305 uniqueSizeBds[2 * nc] > numUniques ||
306 uniqueSizeBds[2 * nc + 1] < numUniques)
307 {
308 cout
309 << " ** ERROR: Expected between " << uniqueSizeBds[2 * nc]
310 << " and " << uniqueSizeBds[2 * nc + 1] << " values\n";
311 ok = false;
312 }
313 }
314 return ok;
315 }
316
TestArrayUniqueValueDetection(int vtkNotUsed (argc),char * vtkNotUsed (argv)[])317 int TestArrayUniqueValueDetection(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
318 {
319 bool ok = true;
320 vtkNew<vtkDoubleArray> darr;
321 vtkNew<vtkIntArray> iarr;
322 vtkNew<vtkStringArray> sarr;
323
324 darr->SetNumberOfComponents(3);
325 darr->SetArray(testTuplesDouble,
326 sizeof(testTuplesDouble)/sizeof(testTuplesDouble[0]), 1);
327 darr->SetName("Some3DPoints - Show off distinct tuple detection");
328 ok &= CheckUniques(darr.GetPointer(), numUniqueDouble, 0., 0.);
329
330 iarr->SetNumberOfComponents(2);
331 iarr->SetArray(testTuplesInt,
332 sizeof(testTuplesInt)/sizeof(testTuplesInt[0]), 1);
333 iarr->SetName("Some2DPoints - Show off tuple non-detection");
334 ok &= CheckUniques(iarr.GetPointer(), numUniqueInt, 0., 0.);
335
336 iarr->SetNumberOfComponents(1);
337 iarr->SetArray(testTuplesInt2,
338 sizeof(testTuplesInt2)/sizeof(testTuplesInt2[0]), 1);
339 //iarr->Modified(); // required since we have changed the tuples?
340 iarr->SetName("Some1DPoints - Show off component non-detection");
341 ok &= CheckUniques(iarr.GetPointer(), numUniqueInt2, 0., 0.);
342
343 sarr->SetNumberOfComponents(1);
344 sarr->SetArray(testTuplesString,
345 sizeof(testTuplesString)/sizeof(testTuplesString[0]), 1);
346 sarr->SetName("SomeNonWords - Show off string value detection");
347 ok &= CheckUniques(sarr.GetPointer(), numUniqueStringComplete, 0.0, 0.0);
348
349 sarr->Modified(); // Verify that modifying the array causes a re-compute
350 sarr->SetName("SomeNonWords - Show off non-exhaustive search");
351 ok &= CheckUniques(sarr.GetPointer(), numUniqueStringSubset, 0.5, 0.1);
352
353 return ok ? 0 : 1;
354 }
355