subcase: Rename subcase_destroy() to subcase_uninit().
[pspp] / src / language / stats / runs.c
index 7e36065730a27818b73f92973f38739840e69c66..8a63b29c96b8e43a582267571e7adaad68e048f7 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis. -*-c-*-
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2010, 2011, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
 
 #include "language/stats/runs.h"
 
+#include <float.h>
 #include <gsl/gsl_cdf.h>
 #include <math.h>
 
 #include "libpspp/misc.h"
 #include "math/percentiles.h"
 #include "math/sort.h"
-#include "output/tab.h"
+#include "output/pivot-table.h"
 
 #include "gettext.h"
+#define N_(msgid) msgid
 #define _(msgid) gettext (msgid)
 
 
@@ -64,7 +66,7 @@ struct run_state
 
 
 /* Return the Z statistic representing the assympototic
-   distribution of the the number of runs */
+   distribution of the number of runs */
 static double
 runs_statistic (const struct run_state *rs)
 {
@@ -76,7 +78,7 @@ runs_statistic (const struct run_state *rs)
 
   z = rs->runs - mu;
 
-  if ( rs->n < 50)
+  if (rs->n < 50)
     {
       if (z <= -0.5)
        z += 0.5;
@@ -99,7 +101,7 @@ runs_statistic (const struct run_state *rs)
 
 static void show_runs_result (const struct runs_test *, const struct run_state *, const struct dictionary *);
 
-void 
+void
 runs_execute (const struct dataset *ds,
              struct casereader *input,
              enum mv_class exclude,
@@ -114,9 +116,9 @@ runs_execute (const struct dataset *ds,
 
   struct one_sample_test *otp = UP_CAST (test, struct one_sample_test, parent);
   struct runs_test *rt = UP_CAST (otp, struct runs_test, parent);
-  struct run_state *rs = xcalloc (otp->n_vars, sizeof (*rs));
+  struct run_state *rs = XCALLOC (otp->n_vars,  struct run_state);
 
-  switch  ( rt->cp_mode)
+  switch  (rt->cp_mode)
     {
     case CP_MODE:
       {
@@ -131,7 +133,7 @@ runs_execute (const struct dataset *ds,
            const struct variable *var = otp->vars[v];
 
            reader = sort_execute_1var (reader, var);
-           
+
            grouper = casegrouper_create_vars (reader, &var, 1);
            last_cc = SYSMIS;
            while (casegrouper_get_next_group (grouper, &group))
@@ -141,22 +143,22 @@ runs_execute (const struct dataset *ds,
                struct ccase *c;
                for (; (c = casereader_read (group)); case_unref (c))
                  {
-                   const double w = weight ? case_data (c, weight)->f: 1.0;
+                   const double w = weight ? case_num (c, weight) : 1.0;
                    const union value *val = case_data (c, var);
-                   if ( var_is_value_missing (var, val, exclude))
+                   if (var_is_value_missing (var, val) & exclude)
                      continue;
                    x = val->f;
                    cc += w;
                  }
 
-               if ( cc > last_cc)
+               if (cc > last_cc)
                  {
                    run->cutpoint = x;
                  }
-               else if ( cc == last_cc)
+               else if (cc == last_cc)
                  {
                    multimodal = true;
-                   if ( x > run->cutpoint)
+                   if (x > run->cutpoint)
                      run->cutpoint = x;
                  }
                last_cc = cc;
@@ -164,8 +166,9 @@ runs_execute (const struct dataset *ds,
              }
            casegrouper_destroy (grouper);
            if (multimodal)
-             msg (MW, _("Multiple modes exist for varible `%s'.  Using %g as the threshold value."),
-                  var_get_name (var), run->cutpoint);
+             msg (MW, _("Multiple modes exist for variable `%s'.  "
+                         "Using %.*g as the threshold value."),
+                  var_get_name (var), DBL_DIG + 1, run->cutpoint);
          }
       }
       break;
@@ -185,11 +188,11 @@ runs_execute (const struct dataset *ds,
            subcase_init_var (&sc, var, SC_ASCEND);
            writer = sort_create_writer (&sc, casereader_get_proto (reader));
 
-           for (; (c = casereader_read (reader)); )
+           for (; (c = casereader_read (reader));)
              {
                const union value *val = case_data (c, var);
-               const double w = weight ? case_data (c, weight)->f: 1.0;
-               if ( var_is_value_missing (var, val, exclude))
+               const double w = weight ? case_num (c, weight) : 1.0;
+               if (var_is_value_missing (var, val) & exclude)
                  {
                    case_unref (c);
                    continue;
@@ -198,13 +201,13 @@ runs_execute (const struct dataset *ds,
                cc += w;
                casewriter_write (writer, c);
              }
-           subcase_destroy (&sc);
+           subcase_uninit (&sc);
            casereader_destroy (reader);
            reader = casewriter_make_reader (writer);
 
            median = percentile_create (0.5, cc);
            os = &median->parent;
-           
+
            order_stats_accumulate (&os, 1,
                                    reader,
                                    weight,
@@ -221,7 +224,7 @@ runs_execute (const struct dataset *ds,
        struct casereader *reader = casereader_clone (input);
        for (; (c = casereader_read (reader)); case_unref (c))
          {
-           const double w = weight ? case_data (c, weight)->f: 1.0;
+           const double w = weight ? case_num (c, weight) : 1.0;
            for (v = 0; v < otp->n_vars; ++v)
              {
                const struct variable *var = otp->vars[v];
@@ -229,7 +232,7 @@ runs_execute (const struct dataset *ds,
                const double x = val->f;
                struct run_state *run = &rs[v];
 
-               if ( var_is_value_missing (var, val, exclude))
+               if (var_is_value_missing (var, val) & exclude)
                  continue;
 
                run->cutpoint += x * w;
@@ -257,7 +260,7 @@ runs_execute (const struct dataset *ds,
 
   for (; (c = casereader_read (input)); case_unref (c))
     {
-      const double w = weight ? case_data (c, weight)->f: 1.0;
+      const double w = weight ? case_num (c, weight) : 1.0;
 
       for (v = 0; v < otp->n_vars; ++v)
        {
@@ -268,7 +271,7 @@ runs_execute (const struct dataset *ds,
          double d = x - run->cutpoint;
          short sign = 0;
 
-         if ( var_is_value_missing (var, val, exclude))
+         if (var_is_value_missing (var, val) & exclude)
            continue;
 
          if (d >= 0)
@@ -306,99 +309,49 @@ runs_execute (const struct dataset *ds,
 static void
 show_runs_result (const struct runs_test *rt, const struct run_state *rs, const struct dictionary *dict)
 {
-  const struct variable *weight = dict_get_weight (dict);
-  const struct fmt_spec *wfmt = weight ? var_get_print_format (weight) : &F_8_0;
-
   const struct one_sample_test *otp = &rt->parent;
 
-  int i;
-  const int row_headers = 1;
-  const int column_headers = 1;
-  struct tab_table *table =
-    tab_create (row_headers + otp->n_vars, column_headers + 7);
-
-  tab_headers (table, row_headers, 0, column_headers, 0);
-
-  tab_title (table, _("Runs Test"));
-
-  /* Box around the table and vertical lines inside*/
-  tab_box (table, TAL_2, TAL_2, -1, TAL_1,
-          0,  0, tab_nc (table) - 1, tab_nr (table) - 1 );
-
-  tab_hline (table, TAL_2, 0, tab_nc (table) -1, column_headers);
-  tab_vline (table, TAL_2, row_headers, 0, tab_nr (table) - 1);
-
-  for (i = 0 ; i < otp->n_vars; ++i)
+  struct pivot_table *table = pivot_table_create (N_("Runs Test"));
+  pivot_table_set_weight_var (table, dict_get_weight (dict));
+
+  pivot_dimension_create (
+    table, PIVOT_AXIS_ROW, N_("Statistics"),
+    (rt->cp_mode == CP_CUSTOM ? N_("Test Value")
+     : rt->cp_mode == CP_MODE ? N_("Test Value (mode)")
+     : rt->cp_mode == CP_MEAN ? N_("Test Value (mean)")
+     : N_("Test Value (median)")), PIVOT_RC_OTHER,
+    N_("Cases < Test Value"), PIVOT_RC_COUNT,
+    N_("Cases ≥ Test Value"), PIVOT_RC_COUNT,
+    N_("Total Cases"), PIVOT_RC_COUNT,
+    N_("Number of Runs"), PIVOT_RC_INTEGER,
+    N_("Z"), PIVOT_RC_OTHER,
+    N_("Asymp. Sig. (2-tailed)"), PIVOT_RC_SIGNIFICANCE);
+
+  struct pivot_dimension *variables = pivot_dimension_create (
+    table, PIVOT_AXIS_COLUMN, N_("Variable"));
+
+  for (size_t i = 0 ; i < otp->n_vars; ++i)
     {
       const struct run_state *run = &rs[i];
 
-      double z = runs_statistic (run);
-
-      tab_text (table,  row_headers + i, 0, 
-               TAT_TITLE | TAB_CENTER ,
-               var_to_string (otp->vars[i]));
-
-      tab_double (table, row_headers +i, 1, 0,
-                 run->cutpoint, 0);
-
-      tab_double (table, row_headers +i, 2, 0,
-                 run->nn, wfmt);
-                 
-      tab_double (table, row_headers +i, 3, 0,
-                 run->np, wfmt);
-
-      tab_double (table, row_headers +i, 4, 0,
-                 run->n, wfmt);
+      int col = pivot_category_create_leaf (
+        variables->root, pivot_value_new_variable (otp->vars[i]));
 
-      tab_double (table, row_headers +i, 5, 0,
-                 run->runs, &F_8_0);
-
-      tab_double (table, row_headers +i, 6, 0,
-                 z, 0);
+      double z = runs_statistic (run);
 
-      tab_double (table, row_headers +i, 7, 0,
-                 2.0 * gsl_cdf_ugaussian_P (z), 0);
+      double rows[] = {
+        run->cutpoint,
+        run->nn,
+        run->np,
+        run->n,
+        run->runs,
+        z,
+        2.0 * (1.0 - gsl_cdf_ugaussian_P (fabs (z))),
+      };
+
+      for (int row = 0; row < sizeof rows / sizeof *rows; row++)
+        pivot_table_put2 (table, row, col, pivot_value_new_number (rows[row]));
     }
 
-  switch  ( rt->cp_mode)
-    {
-    case CP_CUSTOM:
-      tab_text (table,  0, column_headers ,
-               TAT_TITLE | TAB_LEFT , _("Test Value"));
-      break;
-    case CP_MODE:
-      tab_text (table,  0, column_headers ,
-               TAT_TITLE | TAB_LEFT , _("Test Value (mode)"));
-      break;
-    case CP_MEAN:
-      tab_text (table,  0, column_headers ,
-               TAT_TITLE | TAB_LEFT , _("Test Value (mean)"));
-      break;
-    case CP_MEDIAN:
-      tab_text (table,  0, column_headers ,
-               TAT_TITLE | TAB_LEFT , _("Test Value (median)"));
-      break;
-    }
-
-  tab_text (table,  0, column_headers + 1,
-           TAT_TITLE | TAB_LEFT , _("Cases < Test Value"));
-
-  tab_text (table,  0, column_headers + 2,
-           TAT_TITLE | TAB_LEFT , _("Cases ≥ Test Value"));
-
-  tab_text (table,  0, column_headers + 3,
-           TAT_TITLE | TAB_LEFT , _("Total Cases"));
-
-  tab_text (table,  0, column_headers + 4,
-           TAT_TITLE | TAB_LEFT , _("Number of Runs"));
-
-  tab_text (table,  0, column_headers + 5,
-           TAT_TITLE | TAB_LEFT , _("Z"));
-
-  tab_text (table,  0, column_headers + 6,
-           TAT_TITLE | TAB_LEFT , _("Asymp. Sig. (2-tailed)"));
-
-  tab_submit (table);
+  pivot_table_submit (table);
 }
-
-