X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fgraph.c;h=7496b0f0dd7dee0ba80b37c7a4e502b6edda7648;hb=d8dcf1b64a1e3fc0bcb9455564308191e0a5c642;hp=2eeccca2068f9fc1bc8ede8cfc8adbfea502cc97;hpb=3dc0bb90d8aec4d0e85c289c37a5fd03f5d46318;p=pspp diff --git a/src/language/stats/graph.c b/src/language/stats/graph.c index 2eeccca206..7496b0f0dd 100644 --- a/src/language/stats/graph.c +++ b/src/language/stats/graph.c @@ -1,6 +1,6 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2012, 2013, 2015 Free Software Foundation, Inc. + Copyright (C) 2012, 2013, 2015, 2019 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 @@ -240,7 +240,7 @@ parse_function (struct lexer *lexer, struct graph *graph) if (!lex_force_match (lexer, T_LPAREN)) goto error; - graph->dep_vars = xzalloc (sizeof (graph->dep_vars) * graph->n_dep_vars); + graph->dep_vars = xcalloc (graph->n_dep_vars, sizeof (graph->dep_vars)); for (v = 0; v < ag_func[i].arity; ++v) { graph->dep_vars[v] = parse_variable (lexer, graph->dict); @@ -355,8 +355,8 @@ show_histogr (const struct graph *cmd, struct casereader *input) for (;(c = casereader_read (input)) != NULL; case_unref (c)) { - const double x = case_data_idx (c, HG_IDX_X)->f; - const double weight = case_data_idx (c, HG_IDX_WT)->f; + const double x = case_num_idx (c, HG_IDX_X); + const double weight = case_num_idx (c, HG_IDX_WT); moments_pass_two (cmd->es[0].mom, x, weight); histogram_add (histogram, x, weight); } @@ -373,8 +373,8 @@ show_histogr (const struct graph *cmd, struct casereader *input) moments_calculate (cmd->es[0].mom, &n, &mean, &var, NULL, NULL); - chart_item_submit - ( histogram_chart_create (histogram->gsl_hist, + chart_submit + (histogram_chart_create (histogram->gsl_hist, ds_cstr (&label), n, mean, sqrt (var), cmd->normal)); @@ -402,7 +402,7 @@ run_barchart (struct graph *cmd, struct casereader *input) struct casereader *group; double ccc = 0.0; - if ( cmd->missing_pw == false) + if (cmd->missing_pw == false) input = casereader_create_filter_missing (input, cmd->dep_vars, cmd->n_dep_vars, @@ -416,6 +416,8 @@ run_barchart (struct graph *cmd, struct casereader *input) struct freq **cells = NULL; int n_cells = 0; + struct hmap columns = HMAP_INITIALIZER (columns); + assert (cmd->n_by_vars <= 2); for (grouper = casegrouper_create_vars (input, cmd->by_var, cmd->n_by_vars); casegrouper_get_next_group (grouper, &group); @@ -428,8 +430,8 @@ run_barchart (struct graph *cmd, struct casereader *input) for (v = 0; v < cmd->n_by_vars; ++v) { if (var_is_value_missing (cmd->by_var[v], - case_data (c, cmd->by_var[v]), - cmd->fctr_excl)) + case_data (c, cmd->by_var[v])) + & cmd->fctr_excl) break; } @@ -451,6 +453,28 @@ run_barchart (struct graph *cmd, struct casereader *input) if (ag_func[cmd->agr].pre) cells[n_cells - 1]->count = ag_func[cmd->agr].pre(); + if (cmd->n_by_vars > 1) + { + const union value *vv = case_data (c, cmd->by_var[1]); + const double weight = dict_get_case_weight (cmd->dict, c, NULL); + int v1_width = var_get_width (cmd->by_var[1]); + size_t hash = value_hash (vv, v1_width, 0); + + struct freq *fcol = NULL; + HMAP_FOR_EACH_WITH_HASH (fcol, struct freq, node, hash, &columns) + if (value_equal (vv, &fcol->values[0], v1_width)) + break; + + if (fcol) + fcol->count += weight; + else + { + fcol = xzalloc (sizeof *fcol); + fcol->count = weight; + value_clone (&fcol->values[0], vv, v1_width); + hmap_insert (&columns, &fcol->node, hash); + } + } for (v = 0; v < cmd->n_by_vars; ++v) { @@ -465,7 +489,7 @@ run_barchart (struct graph *cmd, struct casereader *input) { const double weight = dict_get_case_weight (cmd->dict,c,NULL); const double x = (cmd->n_dep_vars > 0) - ? case_data (c, cmd->dep_vars[0])->f : SYSMIS; + ? case_num (c, cmd->dep_vars[0]) : SYSMIS; cc += weight; @@ -485,9 +509,39 @@ run_barchart (struct graph *cmd, struct casereader *input) for (int i = 0; i < n_cells; ++i) { if (ag_func[cmd->agr].ppost) - cells[i]->count = ag_func[cmd->agr].ppost (cells[i]->count, ccc); + { + struct freq *cell = cells[i]; + if (cmd->n_by_vars > 1) + { + const union value *vv = &cell->values[1]; + + int v1_width = var_get_width (cmd->by_var[1]); + size_t hash = value_hash (vv, v1_width, 0); + + struct freq *fcol = NULL; + HMAP_FOR_EACH_WITH_HASH (fcol, struct freq, node, hash, &columns) + if (value_equal (vv, &fcol->values[0], v1_width)) + break; + + cell->count = ag_func[cmd->agr].ppost (cell->count, fcol->count); + } + else + cell->count = ag_func[cmd->agr].ppost (cell->count, ccc); + } } + if (cmd->n_by_vars > 1) + { + struct freq *col_cell; + struct freq *next; + HMAP_FOR_EACH_SAFE (col_cell, next, struct freq, node, &columns) + { + + value_destroy (col_cell->values, var_get_width (cmd->by_var[1])); + free (col_cell); + } + } + hmap_destroy (&columns); { struct string label; @@ -501,9 +555,9 @@ run_barchart (struct graph *cmd, struct casereader *input) ds_put_cstr (&label, ag_func[cmd->agr].description); - chart_item_submit (barchart_create (cmd->by_var, cmd->n_by_vars, - ds_cstr (&label), false, - cells, n_cells)); + chart_submit (barchart_create (cmd->by_var, cmd->n_by_vars, + ds_cstr (&label), false, + cells, n_cells)); ds_destroy (&label); } @@ -533,7 +587,7 @@ run_graph (struct graph *cmd, struct casereader *input) /* Always remove cases listwise. This is correct for */ /* the histogram because there is only one variable */ /* and a simple bivariate scatterplot */ - /* if ( cmd->missing_pw == false) */ + /* if (cmd->missing_pw == false) */ input = casereader_create_filter_missing (input, cmd->dep_vars, cmd->n_dep_vars, @@ -555,7 +609,7 @@ run_graph (struct graph *cmd, struct casereader *input) struct ccase *outcase = case_create (cmd->gr_proto); const double weight = dict_get_case_weight (cmd->dict,c,NULL); if (cmd->chart_type == CT_HISTOGRAM) - case_data_rw_idx (outcase, HG_IDX_WT)->f = weight; + *case_num_rw_idx (outcase, HG_IDX_WT) = weight; if (cmd->chart_type == CT_SCATTERPLOT && cmd->n_by_vars > 0) value_copy (case_data_rw_idx (outcase, SP_IDX_BY), case_data (c, cmd->by_var[0]), @@ -563,15 +617,15 @@ run_graph (struct graph *cmd, struct casereader *input) for(int v=0;vn_dep_vars;v++) { const struct variable *var = cmd->dep_vars[v]; - const double x = case_data (c, var)->f; + const double x = case_num (c, var); - if (var_is_value_missing (var, case_data (c, var), cmd->dep_excl)) + if (var_is_value_missing (var, case_data (c, var)) & cmd->dep_excl) { cmd->es[v].missing += weight; continue; } /* Magically v value fits to SP_IDX_X, SP_IDX_Y, HG_IDX_X */ - case_data_rw_idx (outcase, v)->f = x; + *case_num_rw_idx (outcase, v) = x; if (x > cmd->es[v].maximum) cmd->es[v].maximum = x; @@ -747,7 +801,7 @@ cmd_graph (struct lexer *lexer, struct dataset *ds) } else { - lex_error_expecting (lexer, "BIVARIATE", NULL); + lex_error_expecting (lexer, "BIVARIATE"); goto error; } if (!lex_force_match (lexer, T_RPAREN)) @@ -854,7 +908,7 @@ cmd_graph (struct lexer *lexer, struct dataset *ds) } else if (lex_match_id (lexer, "REPORT")) { - graph.fctr_excl = MV_NEVER; + graph.fctr_excl = 0; } else if (lex_match_id (lexer, "NOREPORT")) { @@ -899,7 +953,7 @@ cmd_graph (struct lexer *lexer, struct dataset *ds) case CT_BAR: break; case CT_NONE: - lex_error_expecting (lexer, "HISTOGRAM", "SCATTERPLOT", "BAR", NULL); + lex_error_expecting (lexer, "HISTOGRAM", "SCATTERPLOT", "BAR"); goto error; default: NOT_REACHED ();