X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Faggregate.c;h=9ffa35f5b53bfee2af7a7aaa0a039890866c3f60;hb=cf89e411db41c05c39753b05cf144c8b26a44d96;hp=cb7cff064d2371e87ef9ea08ec75152d1eaf98ec;hpb=14e7292894533c5491a774a2d749386362660812;p=pspp diff --git a/src/aggregate.c b/src/aggregate.c index cb7cff064d..9ffa35f5b5 100644 --- a/src/aggregate.c +++ b/src/aggregate.c @@ -18,7 +18,7 @@ 02111-1307, USA. */ #include -#include +#include "error.h" #include #include "alloc.h" #include "command.h" @@ -26,11 +26,11 @@ #include "file-handle.h" #include "lexer.h" #include "misc.h" +#include "moments.h" #include "pool.h" #include "settings.h" #include "sfm.h" #include "sort.h" -#include "stats.h" #include "str.h" #include "var.h" #include "vfm.h" @@ -53,6 +53,7 @@ struct agr_var int int1, int2; char *string; int missing; + struct moments *moments; }; /* Aggregation functions. */ @@ -169,8 +170,6 @@ cmd_aggregate (void) dict_set_label (agr.dict, dict_get_label (default_dict)); dict_set_documents (agr.dict, dict_get_documents (default_dict)); - lex_match_id ("AGGREGATE"); - /* Read most of the subcommands. */ for (;;) { @@ -326,7 +325,7 @@ create_sysfile (struct agr_proc *agr) struct sfm_write_info w; w.h = agr->out_file; w.dict = agr->dict; - w.compress = set_scompression; + w.compress = get_scompression(); if (!sfm_write_dictionary (&w)) return 0; @@ -513,6 +512,7 @@ parse_aggregate_functions (struct agr_proc *agr) agr->vars = v; tail = v; tail->next = NULL; + v->moments = NULL; /* Create the target variable in the aggregate dictionary. */ @@ -665,6 +665,8 @@ agr_destroy (struct agr_proc *agr) free (iter->arg[i].c); free (iter->string); } + else if (iter->function == SD) + moments_destroy (iter->moments); free (iter); } free (agr->prev_break); @@ -792,8 +794,9 @@ accumulate_aggregate_info (struct agr_proc *agr, { struct agr_var *iter; double weight; + int bad_warn = 1; - weight = dict_get_case_weight (default_dict, input); + weight = dict_get_case_weight (default_dict, input, &bad_warn); for (iter = agr->vars; iter; iter = iter->next) if (iter->src) @@ -827,14 +830,9 @@ accumulate_aggregate_info (struct agr_proc *agr, iter->dbl[0] += v->f * weight; iter->dbl[1] += weight; break; - case SD: - { - double product = v->f * weight; - iter->dbl[0] += product; - iter->dbl[1] += product * v->f; - iter->dbl[2] += weight; - break; - } + case SD: + moments_pass_two (iter->moments, v->f, weight); + break; case MAX: iter->dbl[0] = max (iter->dbl[0], v->f); iter->int1 = 1; @@ -994,9 +992,17 @@ dump_aggregate_info (struct agr_proc *agr, struct ccase *output) v->f = i->dbl[1] != 0.0 ? i->dbl[0] / i->dbl[1] : SYSMIS; break; case SD: - v->f = ((i->dbl[2] > 1.0) - ? calc_stddev (calc_variance (i->dbl, i->dbl[2])) - : SYSMIS); + { + double variance; + + /* FIXME: we should use two passes. */ + moments_calculate (i->moments, NULL, NULL, &variance, + NULL, NULL); + if (variance != SYSMIS) + v->f = sqrt (variance); + else + v->f = SYSMIS; + } break; case MAX: case MIN: @@ -1090,6 +1096,12 @@ initialize_aggregate_info (struct agr_proc *agr) case MAX | FSTRING: memset (iter->string, 0, iter->src->width); break; + case SD: + if (iter->moments == NULL) + iter->moments = moments_create (MOMENT_VARIANCE); + else + moments_clear (iter->moments); + break; default: iter->dbl[0] = iter->dbl[1] = iter->dbl[2] = 0.0; iter->int1 = iter->int2 = 0;