Change how checking for missing values works.
[pspp] / src / language / stats / oneway.c
index 7f28b75b8a45098de84fb736d452642e0ffdde59..6ad71f14c829fc75a91b63e89854f18d9fc3b179 100644 (file)
@@ -1,5 +1,6 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011, 2012, 2013, 2014,
+   2020 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
@@ -168,7 +169,7 @@ df_individual (const struct per_var_ws *pvw UNUSED, const struct moments1 *mom_i
   moments1_calculate (mom_i, &n_i, NULL, &var_i, 0, 0);
   moments1_calculate (mom_j, &n_j, NULL, &var_j, 0, 0);
 
-  if ( n_i <= 1.0 || n_j <= 1.0)
+  if (n_i <= 1.0 || n_j <= 1.0)
     return SYSMIS;
 
   nom = pow2 (var_i/n_i + var_j/n_j);
@@ -191,13 +192,13 @@ static double bonferroni_pinv (double std_err, double alpha, double df, int k, c
 static double sidak_pinv (double std_err, double alpha, double df, int k, const struct moments1 *mom_i UNUSED, const struct moments1 *mom_j UNUSED)
 {
   const double m = k * (k - 1) / 2;
-  double lp = 1.0 - exp (log (1.0 - alpha) / m ) ;
+  double lp = 1.0 - exp (log (1.0 - alpha) / m) ;
   return std_err * gsl_cdf_tdist_Pinv (1.0 - lp / 2.0, df);
 }
 
 static double tukey_pinv (double std_err, double alpha, double df, int k, const struct moments1 *mom_i UNUSED, const struct moments1 *mom_j UNUSED)
 {
-  if ( k < 2 || df < 2)
+  if (k < 2 || df < 2)
     return SYSMIS;
 
   return std_err / sqrt (2.0)  * qtukey (1 - alpha, 1.0, k, df, 1, 0);
@@ -220,7 +221,7 @@ static double gh_pinv (double std_err UNUSED, double alpha, double df, int k, co
 
   m = sqrt ((var_i/n_i + var_j/n_j) / 2.0);
 
-  if ( k < 2 || df < 2)
+  if (k < 2 || df < 2)
     return SYSMIS;
 
   return m * qtukey (1 - alpha, 1.0, k, df, 1, 0);
@@ -236,7 +237,7 @@ multiple_comparison_sig (double std_err,
   int k = pvw->n_groups;
   double df = ph->dff (pvw, dd_i->mom, dd_j->mom);
   double ts = ph->tsf (k, dd_i->mom, dd_j->mom, std_err);
-  if ( df == SYSMIS)
+  if (df == SYSMIS)
     return SYSMIS;
   return  ph->p1f (ts, k - 1, df);
 }
@@ -246,7 +247,7 @@ mc_half_range (const struct oneway_spec *cmd, const struct per_var_ws *pvw, doub
 {
   int k = pvw->n_groups;
   double df = ph->dff (pvw, dd_i->mom, dd_j->mom);
-  if ( df == SYSMIS)
+  if (df == SYSMIS)
     return SYSMIS;
 
   return ph->pinv (std_err, cmd->alpha, df, k, dd_i->mom, dd_j->mom);
@@ -438,7 +439,7 @@ cmd_oneway (struct lexer *lexer, struct dataset *ds)
   ll_init (&oneway.contrast_list);
 
 
-  if ( lex_match (lexer, T_SLASH))
+  if (lex_match (lexer, T_SLASH))
     {
       if (!lex_force_match_id (lexer, "VARIABLES"))
        {
@@ -501,17 +502,17 @@ cmd_oneway (struct lexer *lexer, struct dataset *ds)
                      break;
                    }
                }
-             if ( method == false)
+             if (method == false)
                {
                  if (lex_match_id (lexer, "ALPHA"))
                    {
-                     if ( !lex_force_match (lexer, T_LPAREN))
+                     if (!lex_force_match (lexer, T_LPAREN))
                        goto error;
                      if (! lex_force_num (lexer))
                        goto error;
                      oneway.alpha = lex_number (lexer);
                      lex_get (lexer);
-                     if ( !lex_force_match (lexer, T_RPAREN))
+                     if (!lex_force_match (lexer, T_RPAREN))
                        goto error;
                    }
                  else
@@ -525,7 +526,7 @@ cmd_oneway (struct lexer *lexer, struct dataset *ds)
        }
       else if (lex_match_id (lexer, "CONTRAST"))
        {
-         struct contrasts_node *cl = xzalloc (sizeof *cl);
+         struct contrasts_node *cl = XZALLOC (struct contrasts_node);
 
          struct ll_list *coefficient_list = &cl->coefficient_list;
           lex_match (lexer, T_EQUALS);
@@ -534,7 +535,7 @@ cmd_oneway (struct lexer *lexer, struct dataset *ds)
 
           while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
            {
-             if ( lex_is_number (lexer))
+             if (lex_is_number (lexer))
                {
                  struct coeff_node *cc = xmalloc (sizeof *cc);
                  cc->coeff = lex_number (lexer);
@@ -550,7 +551,7 @@ cmd_oneway (struct lexer *lexer, struct dataset *ds)
                }
            }
 
-         if ( ll_count (coefficient_list) <= 0)
+         if (ll_count (coefficient_list) <= 0)
             {
               destroy_coeff_list (cl);
               goto error;
@@ -708,8 +709,8 @@ run_oneway (const struct oneway_spec *cmd,
   struct oneway_workspace ws;
 
   ws.actual_number_of_groups = 0;
-  ws.vws = xzalloc (cmd->n_vars * sizeof (*ws.vws));
-  ws.dd_total = xmalloc (sizeof (struct descriptive_data) * cmd->n_vars);
+  ws.vws = xcalloc (cmd->n_vars, sizeof (*ws.vws));
+  ws.dd_total = XCALLOC (cmd->n_vars, struct descriptive_data*);
 
   for (v = 0 ; v < cmd->n_vars; ++v)
     ws.dd_total[v] = dd_create (cmd->vars[v]);
@@ -769,9 +770,9 @@ run_oneway (const struct oneway_spec *cmd,
          const struct variable *v = cmd->vars[i];
          const union value *val = case_data (c, v);
 
-         if ( MISS_ANALYSIS == cmd->missing_type)
+         if (MISS_ANALYSIS == cmd->missing_type)
            {
-             if ( var_is_value_missing (v, val, cmd->exclude))
+             if (var_is_value_missing (v, val) & cmd->exclude)
                continue;
            }
 
@@ -782,7 +783,7 @@ run_oneway (const struct oneway_spec *cmd,
   casereader_destroy (reader);
 
   reader = casereader_clone (input);
-  for ( ; (c = casereader_read (reader) ); case_unref (c))
+  for (; (c = casereader_read (reader)); case_unref (c))
     {
       int i;
       double w = dict_get_case_weight (dict, c, NULL);
@@ -792,9 +793,9 @@ run_oneway (const struct oneway_spec *cmd,
          const struct variable *v = cmd->vars[i];
          const union value *val = case_data (c, v);
 
-         if ( MISS_ANALYSIS == cmd->missing_type)
+         if (MISS_ANALYSIS == cmd->missing_type)
            {
-             if ( var_is_value_missing (v, val, cmd->exclude))
+             if (var_is_value_missing (v, val) & cmd->exclude)
                continue;
            }
 
@@ -805,7 +806,7 @@ run_oneway (const struct oneway_spec *cmd,
   casereader_destroy (reader);
 
   reader = casereader_clone (input);
-  for ( ; (c = casereader_read (reader) ); case_unref (c))
+  for (; (c = casereader_read (reader)); case_unref (c))
     {
       int i;
       double w = dict_get_case_weight (dict, c, NULL);
@@ -816,9 +817,9 @@ run_oneway (const struct oneway_spec *cmd,
          const struct variable *v = cmd->vars[i];
          const union value *val = case_data (c, v);
 
-         if ( MISS_ANALYSIS == cmd->missing_type)
+         if (MISS_ANALYSIS == cmd->missing_type)
            {
-             if ( var_is_value_missing (v, val, cmd->exclude))
+             if (var_is_value_missing (v, val) & cmd->exclude)
                continue;
            }
 
@@ -836,7 +837,7 @@ run_oneway (const struct oneway_spec *cmd,
       const struct categoricals *cats = covariance_get_categoricals (pvw->cov);
       const bool ok = categoricals_sane (cats);
 
-      if ( ! ok)
+      if (! ok)
        {
          msg (MW,
               _("Dependent variable %s has no non-missing values.  No analysis for this variable will be done."),
@@ -869,7 +870,7 @@ run_oneway (const struct oneway_spec *cmd,
     {
       const struct categoricals *cats = covariance_get_categoricals (ws.vws[v].cov);
 
-      if ( ! categoricals_is_complete (cats))
+      if (! categoricals_is_complete (cats))
        {
          continue;
        }
@@ -932,7 +933,7 @@ output_oneway (const struct oneway_spec *cmd, struct oneway_workspace *ws)
       ll_for_each (cn, struct coeff_node, ll, cl)
        sum += cn->coeff;
 
-      if ( sum != 0.0 )
+      if (sum != 0.0)
        msg (SW, _("Coefficients for contrast %zu do not total zero"), i);
     }
 
@@ -950,14 +951,14 @@ output_oneway (const struct oneway_spec *cmd, struct oneway_workspace *ws)
       show_contrast_tests (cmd, ws);
     }
 
-  if ( cmd->posthoc )
+  if (cmd->posthoc)
     {
       int v;
       for (v = 0 ; v < cmd->n_vars; ++v)
        {
          const struct categoricals *cats = covariance_get_categoricals (ws->vws[v].cov);
 
-         if ( categoricals_is_complete (cats))
+         if (categoricals_is_complete (cats))
            show_comparisons (cmd, ws, v);
        }
     }
@@ -1316,11 +1317,9 @@ show_contrast_tests (const struct oneway_spec *cmd, const struct oneway_workspac
          df_numerator = pow2 (df_numerator);
 
          double std_error_contrast = sqrt (pvw->mse * coef_msq);
-         double T = fabs (contrast_value / std_error_contrast);
+         double T = contrast_value / std_error_contrast;
          double T_ne = contrast_value / sec_vneq;
          double df_ne = df_numerator / df_denominator;
-          double p_ne = gsl_cdf_tdist_P (T_ne, df_ne);
-          double q_ne = gsl_cdf_tdist_Q (T_ne, df_ne);
 
           struct entry
             {
@@ -1335,13 +1334,13 @@ show_contrast_tests (const struct oneway_spec *cmd, const struct oneway_workspac
               { 1, 0, std_error_contrast },
               { 2, 0, T },
               { 3, 0, df },
-              { 4, 0, 2 * gsl_cdf_tdist_Q (T, df) },
+              { 4, 0, 2 * gsl_cdf_tdist_Q (fabs(T), df) },
               /* Do not assume equal. */
               { 0, 1, contrast_value },
               { 1, 1, sec_vneq },
               { 2, 1, T_ne },
               { 3, 1, df_ne },
-              { 4, 1, 2 * (T > 0 ? q_ne : p_ne) },
+              { 4, 1, 2 * gsl_cdf_tdist_Q (fabs(T_ne), df_ne) },
             };
 
           for (size_t i = 0; i < sizeof entries / sizeof *entries; i++)
@@ -1365,8 +1364,8 @@ show_comparisons (const struct oneway_spec *cmd, const struct oneway_workspace *
   struct pivot_table *table = pivot_table_create__ (
     pivot_value_new_user_text_nocopy (xasprintf (
                                         _("Multiple Comparisons (%s)"),
-                                        var_to_string (cmd->vars[v]))));
-  table->omit_empty = true;
+                                        var_to_string (cmd->vars[v]))),
+    "Multiple Comparisons");
 
   struct pivot_dimension *statistics = pivot_dimension_create (
     table, PIVOT_AXIS_COLUMN, N_("Statistics"),