Fri Dec 19 16:38:35 2003 Ben Pfaff <blp@gnu.org>
authorBen Pfaff <blp@gnu.org>
Sat, 20 Dec 2003 00:44:35 +0000 (00:44 +0000)
committerBen Pfaff <blp@gnu.org>
Sat, 20 Dec 2003 00:44:35 +0000 (00:44 +0000)
* matrix-data.c (compare_factors) Use lexicographical_compare()
algorithm.
(compare_doubles) New function.

* algorithm.c: (lexicographical_compare) New algorithm.

src/ChangeLog
src/algorithm.c
src/algorithm.h
src/matrix-data.c

index f00fddfdeb6986734b938adf935d15d09b526ab4..16b12205848e465c6526a25d182eeceb5c19c92b 100644 (file)
@@ -1,3 +1,11 @@
+Fri Dec 19 16:38:35 2003  Ben Pfaff  <blp@gnu.org>
+
+       * matrix-data.c (compare_factors) Use lexicographical_compare()
+       algorithm.
+       (compare_doubles) New function.
+       
+       * algorithm.c: (lexicographical_compare) New algorithm.
+
 Fri Dec 19 16:23:45 2003  Ben Pfaff  <blp@gnu.org>
 
        * matrix-data.c (compare_variables_by_mxd_vartype): Rewrite.
index ac7f28dfea850da9c092d0b2e50be1e8af3d2b70..c6bdae270e044bb5768536a54c304c363ea4f114 100644 (file)
@@ -362,6 +362,36 @@ binary_search (const void *array, size_t count, size_t size,
     }
   return NULL;
 }
+\f
+/* Lexicographically compares ARRAY1, which contains COUNT1
+   elements of SIZE bytes each, to ARRAY2, which contains COUNT2
+   elements of SIZE bytes, according to COMPARE.  Returns a
+   strcmp()-type result.  AUX is passed to COMPARE as auxiliary
+   data. */
+int
+lexicographical_compare (const void *array1, size_t count1,
+                         const void *array2, size_t count2,
+                         size_t size,
+                         algo_compare_func *compare, void *aux) 
+{
+  const unsigned char *first1 = array1;
+  const unsigned char *first2 = array2;
+  size_t min_count = count1 < count2 ? count1 : count2;
+
+  while (min_count > 0)
+    {
+      int cmp = compare (first1, first2, aux);
+      if (cmp != 0)
+        return cmp;
+
+      first1 += size;
+      first2 += size;
+      min_count--;
+    }
+
+  return count1 < count2 ? -1 : count1 > count2;
+}
+
 \f
 /* Copyright (C) 1991, 1992, 1996, 1997, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
index 2c897bda5d3cb5d8780bdf5429f7b16b59746aa8..d32b5c0737604ea6939255ad1920238361cdf5c8 100644 (file)
@@ -65,11 +65,22 @@ size_t remove_copy_if (const void *array, size_t count, size_t size,
                        void *result,
                        algo_predicate_func *predicate, void *aux);
 
-/* Searches ARRAY, which contains COUNT of SIZE bytes each, for
-   VALUE, using a binary search.  ARRAY must ordered according to
-   COMPARE.  AUX is passed to COMPARE as auxiliary data. */
+/* Searches ARRAY, which contains COUNT elements of SIZE bytes
+   each, for VALUE, using a binary search.  ARRAY must ordered
+   according to COMPARE.  AUX is passed to COMPARE as auxiliary
+   data. */
 void *binary_search (const void *array, size_t count, size_t size,
                      void *value,
                      algo_compare_func *compare, void *aux);
 
+/* Lexicographically compares ARRAY1, which contains COUNT1
+   elements of SIZE bytes each, to ARRAY2, which contains COUNT2
+   elements of SIZE bytes, according to COMPARE.  Returns a
+   strcmp()-type result.  AUX is passed to COMPARE as auxiliary
+   data. */
+int lexicographical_compare (const void *array1, size_t count1,
+                             const void *array2, size_t count2,
+                             size_t size,
+                             algo_compare_func *compare, void *aux);
+
 #endif /* sort-algo.h */
index b2adcd4a8f594fb18cc3bedf6a43d1ac3455ffe9..986186ab9c0f54264ad3b34b609d66332b1f3a8f 100644 (file)
@@ -39,6 +39,7 @@ char *alloca ();
 #include <stdlib.h>
 #include <ctype.h>
 #include <float.h>
+#include "algorithm.h"
 #include "alloc.h"
 #include "command.h"
 #include "data-in.h"
@@ -1641,29 +1642,39 @@ wr_read_splits (void)
   return 1;
 }
 
-/* Return strcmp()-type comparison of the n_factors factors at _A and
-   _B.  Sort missing values toward the end. */
+/* Compares doubles A and B, treating SYSMIS as greatest. */
 static int
-compare_factors (const void *pa, const void *pb)
+compare_doubles (const void *a_, const void *b_, void *aux unused)
 {
-  const double *a = (*(struct factor_data **) pa)->factors;
-  const double *b = (*(struct factor_data **) pb)->factors;
-  int i;
+  const double *a = a_;
+  const double *b = b_;
 
-  for (i = 0; i < n_factors; i++, a++, b++)
-    {
-      if (*a == *b)
-       continue;
-      
-      if (*a == SYSMIS)
-       return 1;
-      else if (*b == SYSMIS)
-       return -1;
-      else
-       return *a - *b < 0 ? -1 : 1;
-    }
+  if (*a == *b)
+    return 0;
+  else if (*a == SYSMIS)
+    return 1;
+  else if (*b == SYSMIS)
+    return -1;
+  else if (*a > *b)
+    return 1;
+  else
+    return -1;
+}
 
-  return 0;
+/* Return strcmp()-type comparison of the n_factors factors at _A and
+   _B.  Sort missing values toward the end. */
+static int
+compare_factors (const void *a_, const void *b_)
+{
+  struct factor_data *const *pa = a_;
+  struct factor_data *const *pb = b_;
+  const double *a = (*pa)->factors;
+  const double *b = (*pb)->factors;
+
+  return lexicographical_compare (a, n_factors,
+                                  b, n_factors,
+                                  sizeof *a,
+                                  compare_doubles, NULL);
 }
 
 /* Write out the data for the current split file to the active