Support moments
[pspp-builds.git] / src / language / stats / descriptives.c
index ccab1931e18d063877afdc0007c4f0a143bdb4ad..edfcca08e4a1f8d4989bb6a7930b1662796af053 100644 (file)
@@ -1,6 +1,5 @@
 /* PSPP - computes sample statistics.
    Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
-   Written by Ben Pfaff <blp@gnu.org>.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -78,7 +77,7 @@ struct dsc_trns
     struct variable **vars;     /* Variables for listwise missing checks. */
     size_t var_cnt;             /* Number of variables. */
     enum dsc_missing_type missing_type; /* Treatment of missing values. */
-    int include_user_missing;   /* Nonzero to include user-missing values. */
+    enum mv_class exclude;      /* Classes of missing values to exclude. */
   };
 
 /* Statistics.  Used as bit indexes, so must be 32 or fewer. */
@@ -151,7 +150,7 @@ struct dsc_proc
 
     /* User options. */
     enum dsc_missing_type missing_type; /* Treatment of missing values. */
-    int include_user_missing;   /* Nonzero to include user-missing values. */
+    enum mv_class exclude;      /* Classes of missing values to exclude. */
     int show_var_labels;        /* Nonzero to show variable labels. */
     int show_index;             /* Nonzero to show variable index. */
     enum dsc_format format;     /* Output format. */
@@ -176,7 +175,7 @@ static bool try_name (const struct dictionary *dict,
                      struct dsc_proc *dsc, const char *name);
 static bool generate_z_varname (const struct dictionary *dict, 
                                struct dsc_proc *dsc, char *z_name,
-                               const char *name, size_t *z_cnt);
+                               const char *name, int *z_cnt);
 static void dump_z_table (struct dsc_proc *);
 static void setup_z_trns (struct dsc_proc *, struct dataset *);
 
@@ -197,7 +196,7 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
   struct variable **vars = NULL;
   size_t var_cnt = 0;
   int save_z_scores = 0;
-  size_t z_cnt = 0;
+  int z_cnt = 0;
   size_t i;
   bool ok;
 
@@ -206,7 +205,7 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
   dsc->vars = NULL;
   dsc->var_cnt = 0;
   dsc->missing_type = DSC_VARIABLE;
-  dsc->include_user_missing = 0;
+  dsc->exclude = MV_ANY;
   dsc->show_var_labels = 1;
   dsc->show_index = 0;
   dsc->format = DSC_LINE;
@@ -230,7 +229,7 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
               else if (lex_match_id (lexer, "LISTWISE"))
                 dsc->missing_type = DSC_LISTWISE;
               else if (lex_match_id (lexer, "INCLUDE"))
-                dsc->include_user_missing = 1;
+                dsc->exclude = MV_SYSTEM;
               else
                 {
                   lex_error (lexer, NULL);
@@ -371,7 +370,7 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
     {
       if (save_z_scores) 
         {
-          size_t gen_cnt = 0;
+          int gen_cnt = 0;
 
           for (i = 0; i < dsc->var_cnt; i++)
             if (dsc->vars[i].z_name[0] == 0) 
@@ -492,7 +491,7 @@ try_name (const struct dictionary *dict, struct dsc_proc *dsc,
    copies the new name into Z_NAME.  On failure, returns false. */
 static bool
 generate_z_varname (const struct dictionary *dict, struct dsc_proc *dsc, char *z_name,
-                    const char *var_name, size_t *z_cnt)
+                    const char *var_name, int *z_cnt)
 {
   char name[LONG_NAME_LEN + 1];
 
@@ -596,9 +595,7 @@ descriptives_trns_proc (void *trns_, struct ccase * c,
       for (vars = t->vars; vars < t->vars + t->var_cnt; vars++)
        {
          double score = case_num (c, *vars);
-         if ( score == SYSMIS
-               || (!t->include_user_missing 
-                   && var_is_num_user_missing (*vars, score)))
+         if (var_is_num_missing (*vars, score, t->exclude))
            {
              all_sysmis = 1;
              break;
@@ -611,10 +608,8 @@ descriptives_trns_proc (void *trns_, struct ccase * c,
       double input = case_num (c, z->src_var);
       double *output = &case_data_rw (c, z->z_var)->f;
 
-      if (z->mean == SYSMIS || z->std_dev == SYSMIS 
-         || all_sysmis || input == SYSMIS 
-         || (!t->include_user_missing
-              && var_is_num_user_missing (z->src_var, input)))
+      if (z->mean == SYSMIS || z->std_dev == SYSMIS || all_sysmis
+          || var_is_num_missing (z->src_var, input, t->exclude))
        *output = SYSMIS;
       else
        *output = (input - z->mean) / z->std_dev;
@@ -649,7 +644,7 @@ setup_z_trns (struct dsc_proc *dsc, struct dataset *ds)
   t->z_scores = xnmalloc (cnt, sizeof *t->z_scores);
   t->z_score_cnt = cnt;
   t->missing_type = dsc->missing_type;
-  t->include_user_missing = dsc->include_user_missing;
+  t->exclude = dsc->exclude;
   if ( t->missing_type == DSC_LISTWISE )
     {
       t->var_cnt = dsc->var_cnt;
@@ -742,9 +737,7 @@ calc_descriptives (const struct ccase *first,
           double x = case_num (&c, dv->v);
           
           if (dsc->missing_type != DSC_LISTWISE
-              && (x == SYSMIS
-                  || (!dsc->include_user_missing
-                      && var_is_num_user_missing (dv->v, x))))
+              && var_is_num_missing (dv->v, x, dsc->exclude))
             {
               dv->missing += weight;
               continue;
@@ -774,8 +767,7 @@ calc_descriptives (const struct ccase *first,
             continue;
       
           /* Check for missing values. */
-          if (listwise_missing (dsc, &c) 
-              && dsc->missing_type == DSC_LISTWISE)
+          if (dsc->missing_type == DSC_LISTWISE && listwise_missing (dsc, &c))
             continue; 
 
           for (i = 0; i < dsc->var_cnt; i++) 
@@ -784,9 +776,7 @@ calc_descriptives (const struct ccase *first,
               double x = case_num (&c, dv->v);
           
               if (dsc->missing_type != DSC_LISTWISE
-                  && (x == SYSMIS
-                      || (!dsc->include_user_missing
-                          && var_is_num_user_missing (dv->v, x))))
+                  && var_is_num_missing (dv->v, x, dsc->exclude))
                 continue;
 
               if (dv->moments != NULL)
@@ -850,9 +840,7 @@ listwise_missing (struct dsc_proc *dsc, const struct ccase *c)
       struct dsc_var *dv = &dsc->vars[i];
       double x = case_num (c, dv->v);
 
-      if (x == SYSMIS
-          || (!dsc->include_user_missing
-              && var_is_num_user_missing (dv->v, x)))
+      if (var_is_num_missing (dv->v, x, dsc->exclude))
         return true;
     }
   return false;