Move all command implementations into a single 'commands' directory.
[pspp] / tests / language / commands / quick-cluster.at
1 dnl PSPP - a program for statistical analysis.
2 dnl Copyright (C) 2017 Free Software Foundation, Inc.
3 dnl
4 dnl This program is free software: you can redistribute it and/or modify
5 dnl it under the terms of the GNU General Public License as published by
6 dnl the Free Software Foundation, either version 3 of the License, or
7 dnl (at your option) any later version.
8 dnl
9 dnl This program is distributed in the hope that it will be useful,
10 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
11 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 dnl GNU General Public License for more details.
13 dnl
14 dnl You should have received a copy of the GNU General Public License
15 dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 dnl
17 AT_BANNER([QUICK CLUSTER])
18
19 AT_SETUP([QUICK CLUSTER with small data set])
20 AT_DATA([quick-cluster.sps], [dnl
21 DATA LIST LIST /x y z.
22 BEGIN DATA.
23 22,2930,4099
24 17,3350,4749
25 22,2640,3799
26 20, 3250,4816
27 15,4080,7827
28 4,5,4
29 5,6,5
30 6,7,6
31 7,8,7
32 8,9,8
33 9,10,9
34 END DATA.
35 QUICK CLUSTER x y z
36   /CRITERIA=CLUSTER(2) MXITER(20).
37 ])
38 AT_CHECK([pspp -o pspp.csv quick-cluster.sps])
39 AT_CHECK([cat pspp.csv], [0], [dnl
40 Table: Reading free-form data from INLINE.
41 Variable,Format
42 x,F8.0
43 y,F8.0
44 z,F8.0
45
46 Table: Final Cluster Centers
47 ,Cluster,
48 ,1,2
49 x,6.50,19.20
50 y,7.50,3250.00
51 z,6.50,5058.00
52
53 Table: Number of Cases in each Cluster
54 ,,Count
55 Cluster,1,6
56 ,2,5
57 Valid,,11
58 ])
59 AT_CLEANUP
60
61 AT_SETUP([QUICK CLUSTER with large data set])
62 AT_KEYWORDS([slow])
63 AT_DATA([quick-cluster.sps], [dnl
64 input program.
65 loop #i = 1 to 50000.
66 compute x = 3.
67 end case.
68 end loop.
69 end file.
70 end input program.
71 QUICK CLUSTER x /CRITERIA = CLUSTER(4) NOINITIAL.
72 ])
73 AT_CHECK([pspp -o pspp.csv quick-cluster.sps])
74 AT_CHECK([cat pspp.csv], [0], [dnl
75 Table: Final Cluster Centers
76 ,Cluster,,,
77 ,1,2,3,4
78 x,NaN,NaN,NaN,3.00
79
80 Table: Number of Cases in each Cluster
81 ,,Count
82 Cluster,1,0
83 ,2,0
84 ,3,0
85 ,4,50000
86 Valid,,50000
87 ])
88 AT_CLEANUP
89
90
91 AT_SETUP([QUICK CLUSTER with weights])
92 AT_DATA([qc-weighted.sps], [dnl
93 input program.
94 loop #i = 1 to 400.
95  compute x = mod (#i, 4).
96  compute w = 5.
97  end case.
98 end loop.
99 loop #i = 1 to 400.
100  compute x = mod (#i, 4).
101  compute w = 3.
102  end case.
103 end loop.
104 end file.
105 end input program.
106
107 weight by w.
108
109 QUICK CLUSTER x /CRITERIA = CLUSTER(4) MXITER (10).
110 ])
111
112 AT_CHECK([pspp -o pspp-w.csv qc-weighted.sps])
113
114
115 AT_DATA([qc-unweighted.sps], [dnl
116 input program.
117 loop #i = 1 to 3200.
118  compute x = mod (#i, 4).
119  end case.
120 end loop.
121 end file.
122 end input program.
123
124 QUICK CLUSTER x /CRITERIA = CLUSTER(4) MXITER (10).
125 ])
126
127 AT_CHECK([pspp -o pspp-unw.csv qc-unweighted.sps])
128
129 AT_CHECK([diff pspp-w.csv pspp-unw.csv], [0])
130
131 AT_CLEANUP
132
133 AT_SETUP([QUICK CLUSTER with listwise missing])
134 AT_DATA([quick-miss.sps], [dnl
135 data list notable list /x *.
136 begin data.
137 1
138 1
139 2
140 3
141 4
142 .
143 2
144 end data.
145
146 QUICK CLUSTER x /CRITERIA = CLUSTER(4) MXITER (10).
147 ])
148
149 AT_CHECK([pspp -o pspp-m.csv quick-miss.sps])
150
151 AT_DATA([quick-nmiss.sps], [dnl
152 data list notable list /x *.
153 begin data.
154 1
155 1
156 2
157 3
158 4
159 2
160 end data.
161
162 QUICK CLUSTER x /CRITERIA = CLUSTER(4) MXITER (10).
163 ])
164
165 AT_CHECK([pspp -o pspp-nm.csv quick-nmiss.sps])
166
167 AT_CHECK([diff pspp-m.csv pspp-nm.csv], [0])
168
169 AT_CLEANUP
170
171
172 AT_SETUP([QUICK CLUSTER with pairwise missing])
173
174 dnl This test runs two programs, which are identical except that one
175 dnl has an extra case with one missing value. Because the syntax uses
176 dnl NOINITIAL and NOUPDATE, the results should be identical except for
177 dnl the final classification.
178
179 AT_DATA([quick-s.sps], [dnl
180 data list notable list /x * y *.
181 begin data.
182 1   2
183 1   2.2
184 1.1 1.9
185 1   9
186 1   10
187 1.3 9.5
188 0.9 8.9
189 3.5 2
190 3.4 3
191 3.5 2.5
192 3.1 2.0
193 end data.
194
195 QUICK CLUSTER x y
196         /PRINT = INITIAL
197         /CRITERIA = CLUSTER(3) NOINITIAL NOUPDATE
198         .
199 ])
200
201 AT_CHECK([pspp -O format=csv quick-s.sps  > pspp-s.csv])
202
203 AT_DATA([quick-pw.sps], [dnl
204 data list notable list /x * y *.
205 begin data.
206 1   2
207 1   2.2
208 1.1 1.9
209 1   9
210 1   10
211 1.3 9.5
212 0.9 8.9
213 3.5 2
214 3.4 3
215 3.5 2.5
216 3.1 2.0
217 .   2.3
218 end data.
219
220 QUICK CLUSTER x y
221         /CRITERIA = CLUSTER(3) NOINITIAL NOUPDATE
222         /PRINT = INITIAL
223         /MISSING = PAIRWISE
224         .
225 ])
226
227 AT_CHECK([pspp -O format=csv quick-pw.sps  > pspp-pw.csv])
228
229 AT_CHECK([head -n 13  pspp-s.csv > top-s.csv])
230 AT_CHECK([head -n 13  pspp-pw.csv > top-pw.csv])
231 AT_CHECK([diff top-s.csv top-pw.csv])
232
233
234 AT_CHECK([grep Valid pspp-s.csv], [0], [Valid,,11
235 ])
236
237 AT_CHECK([grep Valid pspp-pw.csv], [0], [Valid,,12
238 ])
239
240
241 AT_CLEANUP
242
243
244
245 AT_SETUP([QUICK CLUSTER crash on bad cluster quantity])
246 AT_DATA([badn.sps], [dnl
247 data list notable list /x * y *.
248 begin data.
249 1   2
250 1   2.2
251 end data.
252
253 QUICK CLUSTER x y
254         /CRITERIA = CLUSTER(0)
255         .
256 ])
257
258 AT_CHECK([pspp -O format=csv badn.sps], [1], [ignore])
259
260 AT_CLEANUP
261
262 AT_SETUP([QUICK CLUSTER infinite loop on bad command name])
263 AT_DATA([quick-cluster.sps], [dnl
264 data list notable list /x y.
265 begin data.
266 1   2
267 1   2.2
268 end data.
269
270 QUICK CLUSTER x y /UNSUPPORTED.
271 ])
272 AT_CHECK([pspp -O format=csv quick-cluster.sps], [1], [dnl
273 "quick-cluster.sps:7.20-7.30: error: QUICK CLUSTER: Syntax error expecting MISSING, PRINT, SAVE, or CRITERIA.
274     7 | QUICK CLUSTER x y /UNSUPPORTED.
275       |                    ^~~~~~~~~~~"
276 ])
277 AT_CLEANUP
278
279
280
281 AT_SETUP([QUICK CLUSTER /PRINT subcommand])
282 AT_DATA([quick-cluster.sps], [dnl
283 data list notable list /cluster (A8) x y (F8.0).
284 begin data.
285 A 10.45 9.38
286 A 10.67 9.17
287 A 10.86 9.63
288 A 8.77 8.45
289 A 8.04 11.77
290 A 10.34 9.83
291 A 10.37 10.54
292 A 11.49 8.18
293 A 10.17 11.10
294 A 11.37 9.16
295 A 10.25 8.83
296 A 8.69 9.92
297 A 10.36 10.39
298 A 10.89 10.51
299 A 9.9 11.39
300 A 11.1 10.91
301 A 11.77 8.47
302 A 9.5 10.46
303 B -11.01 -9.21
304 B -10.8 -11.76
305 B -10.03 -10.29
306 B -9.54 -9.17
307 B -10.16 -9.82
308 B -10.01 -8.63
309 B -9.6 -10.22
310 B -11.36 -10.93
311 B -10.63 -10.97
312 B -9.53 -10.78
313 B -9.40 -10.26
314 B -10.76 -9.76
315 B -9.9 -10.11
316 B -10.16 -9.75
317 B -8.65 -11.31
318 B -10.10 -10.90
319 B -11.67 -9.89
320 B -11.11 -9.23
321 B -8.7 -8.43
322 B -11.35 -8.68
323 C -10.20 9.00
324 C -10.12 9.92
325 C -10.41 10.16
326 C -9.86 10.12
327 C -10.31 10.12
328 C -9.57 10.16
329 C -9.69 9.93
330 C -9.14 10.84
331 C -9.8 10.19
332 C -9.97 10.22
333 C -11.65 10.81
334 C -9.80 11.39
335 C -10.31 10.74
336 C -10.26 10.38
337 C -11.57 10.02
338 C -10.50 9.75
339 C -9.06 9.63
340 C -10.17 10.82
341 C -10.22 9.99
342 end data.
343
344 QUICK CLUSTER x y
345   /CRITERIA=CLUSTERS(3)
346   /PRINT=INITIAL CLUSTER.
347 ])
348
349 AT_CHECK([pspp -O format=csv quick-cluster.sps], [0], [dnl
350 Table: Initial Cluster Centers
351 ,Cluster,,
352 ,1,2,3
353 x,-11,-12,11
354 y,-12,11,11
355
356 Table: Final Cluster Centers
357 ,Cluster,,
358 ,1,2,3
359 x,-10,-10,10
360 y,-10,10,10
361
362 Table: Number of Cases in each Cluster
363 ,,Count
364 Cluster,1,20
365 ,2,19
366 ,3,18
367 Valid,,57
368
369 Table: Cluster Membership
370 Case Number,Cluster
371 1,3
372 2,3
373 3,3
374 4,3
375 5,3
376 6,3
377 7,3
378 8,3
379 9,3
380 10,3
381 11,3
382 12,3
383 13,3
384 14,3
385 15,3
386 16,3
387 17,3
388 18,3
389 19,1
390 20,1
391 21,1
392 22,1
393 23,1
394 24,1
395 25,1
396 26,1
397 27,1
398 28,1
399 29,1
400 30,1
401 31,1
402 32,1
403 33,1
404 34,1
405 35,1
406 36,1
407 37,1
408 38,1
409 39,2
410 40,2
411 41,2
412 42,2
413 43,2
414 44,2
415 45,2
416 46,2
417 47,2
418 48,2
419 49,2
420 50,2
421 51,2
422 52,2
423 53,2
424 54,2
425 55,2
426 56,2
427 57,2
428 ])
429
430 AT_CLEANUP
431
432
433 dnl Test for a crash which happened on bad input syntax
434 AT_SETUP([QUICK CLUSTER -- Empty Parentheses])
435
436 AT_DATA([empty-parens.sps], [dnl
437 data list notable list /x * y *.
438 begin data.
439 1   2
440 1   2.2
441 end data.
442
443 QUICK CLUSTER x y
444         /CRITERIA = CONVERGE()
445         .
446 ])
447
448 AT_CHECK([pspp -o pspp.csv empty-parens.sps], [1], [ignore])
449
450 AT_CLEANUP
451
452
453
454 AT_SETUP([QUICK CLUSTER with save])
455 AT_DATA([quick-cluster.sps], [dnl
456 DATA LIST notable LIST /x y z.
457 BEGIN DATA.
458 22,2930,4099
459 17,3350,4749
460 22,2640,3799
461 20, 3250,4816
462 15,4080,7827
463 4,5,4
464 5,6,5
465 6,7,6
466 7,8,7
467 8,9,8
468 9,10,9
469 END DATA.
470 QUICK CLUSTER x y z
471   /CRITERIA=CLUSTER(2) MXITER(20)
472   /SAVE = CLUSTER (cluster) DISTANCE (distance).
473
474 list.
475 ])
476
477 AT_CHECK([pspp -O format=csv quick-cluster.sps], [0], [dnl
478 Table: Final Cluster Centers
479 ,Cluster,
480 ,1,2
481 x,6.50,19.20
482 y,7.50,3250.00
483 z,6.50,5058.00
484
485 Table: Number of Cases in each Cluster
486 ,,Count
487 Cluster,1,6
488 ,2,5
489 Valid,,11
490
491 Table: Data List
492 x,y,z,cluster,distance
493 22.00,2930.00,4099.00,2.00,1010.98
494 17.00,3350.00,4749.00,2.00,324.79
495 22.00,2640.00,3799.00,2.00,1399.00
496 20.00,3250.00,4816.00,2.00,242.00
497 15.00,4080.00,7827.00,2.00,2890.72
498 4.00,5.00,4.00,1.00,4.33
499 5.00,6.00,5.00,1.00,2.60
500 6.00,7.00,6.00,1.00,.87
501 7.00,8.00,7.00,1.00,.87
502 8.00,9.00,8.00,1.00,2.60
503 9.00,10.00,9.00,1.00,4.33
504 ])
505 AT_CLEANUP
506
507
508 AT_SETUP([QUICK CLUSTER with single save])
509 AT_DATA([quick-cluster.sps], [dnl
510 DATA LIST notable LIST /x y z.
511 BEGIN DATA.
512 22,2930,4099
513 17,3350,4749
514 22,2640,3799
515 20, 3250,4816
516 15,4080,7827
517 4,5,4
518 5,6,5
519 6,7,6
520 7,8,7
521 8,9,8
522 9,10,9
523 END DATA.
524 QUICK CLUSTER x y z
525   /CRITERIA=CLUSTER(2) MXITER(20)
526   /SAVE = DISTANCE.
527
528 list.
529 ])
530
531 AT_CHECK([pspp -O format=csv quick-cluster.sps], [0], [dnl
532 Table: Final Cluster Centers
533 ,Cluster,
534 ,1,2
535 x,6.50,19.20
536 y,7.50,3250.00
537 z,6.50,5058.00
538
539 Table: Number of Cases in each Cluster
540 ,,Count
541 Cluster,1,6
542 ,2,5
543 Valid,,11
544
545 Table: Data List
546 x,y,z,QCL_0
547 22.00,2930.00,4099.00,1010.98
548 17.00,3350.00,4749.00,324.79
549 22.00,2640.00,3799.00,1399.00
550 20.00,3250.00,4816.00,242.00
551 15.00,4080.00,7827.00,2890.72
552 4.00,5.00,4.00,4.33
553 5.00,6.00,5.00,2.60
554 6.00,7.00,6.00,.87
555 7.00,8.00,7.00,.87
556 8.00,9.00,8.00,2.60
557 9.00,10.00,9.00,4.33
558 ])
559 AT_CLEANUP
560
561
562 dnl This one was noticed to crash at one point.
563 AT_SETUP([QUICK CLUSTER crash on bizarre input])
564 AT_DATA([badn.sps], [dnl
565 data list notable list /x.
566 begin da\a*
567 22
568 17
569 22
570 22
571 15
572 4,
573 5,
574 6,
575 7,j8,
576 9,
577 end data.
578
579 quick cluster x
580 " /criteria=cluster(2) mxiter(20)
581   /save = distance
582   .
583
584 list.
585 ]) dnl "
586
587 AT_CHECK([pspp -O format=csv badn.sps], [1], [ignore])
588
589 AT_CLEANUP
590
591 AT_SETUP([QUICK CLUSTER syntax errors])
592 AT_DATA([quick-cluster.sps], [dnl
593 DATA LIST LIST NOTABLE /x y.
594 QUICK CLUSTER **.
595 QUICK CLUSTER x/MISSING=**.
596 QUICK CLUSTER x/PRINT=**.
597 QUICK CLUSTER x/SAVE=CLUSTER(**).
598 QUICK CLUSTER x/SAVE=CLUSTER(x).
599 QUICK CLUSTER x/SAVE=CLUSTER(c **).
600 QUICK CLUSTER x/SAVE=DISTANCE(**).
601 QUICK CLUSTER x/SAVE=DISTANCE(x).
602 QUICK CLUSTER x/SAVE=DISTANCE(d **).
603 QUICK CLUSTER x/SAVE=**.
604 QUICK CLUSTER x/CRITERIA=CLUSTERS **.
605 QUICK CLUSTER x/CRITERIA=CLUSTERS(**).
606 QUICK CLUSTER x/CRITERIA=CLUSTERS(5 **).
607 QUICK CLUSTER x/CRITERIA=CONVERGE **.
608 QUICK CLUSTER x/CRITERIA=CONVERGE(**).
609 QUICK CLUSTER x/CRITERIA=CONVERGE(5 **).
610 QUICK CLUSTER x/CRITERIA=**.
611 QUICK CLUSTER x/ **.
612 ])
613 AT_CHECK([pspp -O format=csv quick-cluster.sps], [1], [dnl
614 "quick-cluster.sps:2.15-2.16: error: QUICK CLUSTER: Syntax error expecting variable name.
615     2 | QUICK CLUSTER **.
616       |               ^~"
617
618 "quick-cluster.sps:3.25-3.26: error: QUICK CLUSTER: Syntax error expecting LISTWISE, DEFAULT, PAIRWISE, INCLUDE, or EXCLUDE.
619     3 | QUICK CLUSTER x/MISSING=**.
620       |                         ^~"
621
622 "quick-cluster.sps:4.23-4.24: error: QUICK CLUSTER: Syntax error expecting CLUSTER or INITIAL.
623     4 | QUICK CLUSTER x/PRINT=**.
624       |                       ^~"
625
626 "quick-cluster.sps:5.30-5.31: error: QUICK CLUSTER: Syntax error expecting identifier.
627     5 | QUICK CLUSTER x/SAVE=CLUSTER(**).
628       |                              ^~"
629
630 "quick-cluster.sps:6.30: error: QUICK CLUSTER: A variable called `x' already exists.
631     6 | QUICK CLUSTER x/SAVE=CLUSTER(x).
632       |                              ^"
633
634 "quick-cluster.sps:7.32-7.33: error: QUICK CLUSTER: Syntax error expecting `@:}@'.
635     7 | QUICK CLUSTER x/SAVE=CLUSTER(c **).
636       |                                ^~"
637
638 "quick-cluster.sps:8.31-8.32: error: QUICK CLUSTER: Syntax error expecting identifier.
639     8 | QUICK CLUSTER x/SAVE=DISTANCE(**).
640       |                               ^~"
641
642 "quick-cluster.sps:9.31: error: QUICK CLUSTER: A variable called `x' already exists.
643     9 | QUICK CLUSTER x/SAVE=DISTANCE(x).
644       |                               ^"
645
646 "quick-cluster.sps:10.33-10.34: error: QUICK CLUSTER: Syntax error expecting `@:}@'.
647    10 | QUICK CLUSTER x/SAVE=DISTANCE(d **).
648       |                                 ^~"
649
650 "quick-cluster.sps:11.22-11.23: error: QUICK CLUSTER: Syntax error expecting CLUSTER or DISTANCE.
651    11 | QUICK CLUSTER x/SAVE=**.
652       |                      ^~"
653
654 "quick-cluster.sps:12.35-12.36: error: QUICK CLUSTER: Syntax error expecting `('.
655    12 | QUICK CLUSTER x/CRITERIA=CLUSTERS **.
656       |                                   ^~"
657
658 "quick-cluster.sps:13.35-13.36: error: QUICK CLUSTER: Syntax error expecting positive integer for CLUSTERS.
659    13 | QUICK CLUSTER x/CRITERIA=CLUSTERS(**).
660       |                                   ^~"
661
662 "quick-cluster.sps:14.37-14.38: error: QUICK CLUSTER: Syntax error expecting `)'.
663    14 | QUICK CLUSTER x/CRITERIA=CLUSTERS(5 **).
664       |                                     ^~"
665
666 "quick-cluster.sps:15.35-15.36: error: QUICK CLUSTER: Syntax error expecting `('.
667    15 | QUICK CLUSTER x/CRITERIA=CONVERGE **.
668       |                                   ^~"
669
670 "quick-cluster.sps:16.35-16.36: error: QUICK CLUSTER: Syntax error expecting positive number for CONVERGE.
671    16 | QUICK CLUSTER x/CRITERIA=CONVERGE(**).
672       |                                   ^~"
673
674 "quick-cluster.sps:17.37-17.38: error: QUICK CLUSTER: Syntax error expecting `)'.
675    17 | QUICK CLUSTER x/CRITERIA=CONVERGE(5 **).
676       |                                     ^~"
677
678 "quick-cluster.sps:18.26-18.27: error: QUICK CLUSTER: Syntax error expecting CLUSTERS, CONVERGE, MXITER, NOINITIAL, or NOUPDATE.
679    18 | QUICK CLUSTER x/CRITERIA=**.
680       |                          ^~"
681
682 "quick-cluster.sps:19.18-19.19: error: QUICK CLUSTER: Syntax error expecting MISSING, PRINT, SAVE, or CRITERIA.
683    19 | QUICK CLUSTER x/ **.
684       |                  ^~"
685 ])
686 AT_CLEANUP