int main(int argc, char *argv[]) { struct GModule *module; struct Option *map_opt, *type_opt, *field_opt, *col_opt, *where_opt, *percentile; struct Flag *shell_flag, *extended; struct Map_info Map; struct field_info *Fi; dbDriver *Driver; dbCatValArray Cvarr; struct line_pnts *Points; struct line_cats *Cats; int otype, ofield; int compatible = 1; /* types are compatible: point+centroid or line+boundary or area */ int nrec, ctype, nlines, line, nareas, area; int nmissing = 0; /* number of missing atttributes */ int nnull = 0; /* number of null values */ int first = 1; /* Statistics */ int count = 0; /* number of features with non-null attribute */ double sum = 0.0; double sumsq = 0.0; double sumcb = 0.0; double sumqt = 0.0; double sum_abs = 0.0; double min = 0.0 / 0.0; /* init as nan */ double max = 0.0 / 0.0; double mean, mean_abs, pop_variance, sample_variance, pop_stdev, sample_stdev, pop_coeff_variation, kurtosis, skewness; double total_size = 0.0; /* total size: length/area */ /* Extended statistics */ int perc; module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("statistics")); module->label = _("Calculates univariate statistics for attribute."); module->description = _("Variance and standard " "deviation is calculated only for points if specified."); map_opt = G_define_standard_option(G_OPT_V_MAP); field_opt = G_define_standard_option(G_OPT_V_FIELD); type_opt = G_define_standard_option(G_OPT_V_TYPE); type_opt->options = "point,line,boundary,centroid,area"; col_opt = G_define_standard_option(G_OPT_DB_COLUMN); col_opt->required = YES; where_opt = G_define_standard_option(G_OPT_DB_WHERE); percentile = G_define_option(); percentile->key = "percentile"; percentile->type = TYPE_INTEGER; percentile->required = NO; percentile->options = "0-100"; percentile->answer = "90"; percentile->description = _("Percentile to calculate (requires extended statistics flag)"); shell_flag = G_define_flag(); shell_flag->key = 'g'; shell_flag->description = _("Print the stats in shell script style"); extended = G_define_flag(); extended->key = 'e'; extended->description = _("Calculate extended statistics"); G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); otype = Vect_option_to_types(type_opt); perc = atoi(percentile->answer); Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); /* open input vector */ Vect_set_open_level(2); Vect_open_old2(&Map, map_opt->answer, "", field_opt->answer); ofield = Vect_get_field_number(&Map, field_opt->answer); /* Check if types are compatible */ if ((otype & GV_POINTS) && ((otype & GV_LINES) || (otype & GV_AREA))) compatible = 0; if ((otype & GV_LINES) && (otype & GV_AREA)) compatible = 0; if (!compatible) { G_warning(_("Incompatible vector type(s) specified, only number of features, minimum, maximum and range " "can be calculated")); } if (extended->answer && !(otype & GV_POINTS)) { G_warning(_("Extended statistics is currently supported only for points/centroids")); } /* Read attributes */ db_CatValArray_init(&Cvarr); Fi = Vect_get_field(&Map, ofield); if (Fi == NULL) { G_fatal_error(_(" Database connection not defined for layer <%s>"), field_opt->answer); } Driver = db_start_driver_open_database(Fi->driver, Fi->database); if (Driver == NULL) G_fatal_error("Unable to open database <%s> by driver <%s>", Fi->database, Fi->driver); /* Note do not check if the column exists in the table because it may be an expression */ nrec = db_select_CatValArray(Driver, Fi->table, Fi->key, col_opt->answer, where_opt->answer, &Cvarr); G_debug(2, "nrec = %d", nrec); ctype = Cvarr.ctype; if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("Column type not supported")); if (nrec < 0) G_fatal_error(_("Unable to select data from table")); db_close_database_shutdown_driver(Driver); /* Lines */ nlines = Vect_get_num_lines(&Map); for (line = 1; line <= nlines; line++) { int i, type; G_debug(3, "line = %d", line); type = Vect_read_line(&Map, Points, Cats, line); if (!(type & otype)) continue; for (i = 0; i < Cats->n_cats; i++) { if (Cats->field[i] == ofield) { double val; dbCatVal *catval; G_debug(3, "cat = %d", Cats->cat[i]); if (db_CatValArray_get_value(&Cvarr, Cats->cat[i], &catval) != DB_OK) { G_debug(3, "No record for cat = %d", Cats->cat[i]); nmissing++; continue; } if (catval->isNull) { G_debug(3, "NULL value for cat = %d", Cats->cat[i]); nnull++; continue; } if (ctype == DB_C_TYPE_INT) { val = catval->val.i; } else if (ctype == DB_C_TYPE_DOUBLE) { val = catval->val.d; } count++; if (first) { max = val; min = val; first = 0; } else { if (val > max) max = val; if (val < min) min = val; } if (compatible) { if (type & GV_POINTS) { sum += val; sumsq += val * val; sumcb += val * val * val; sumqt += val * val * val * val; sum_abs += fabs(val); } else { /* GV_LINES */ double l; l = Vect_line_length(Points); sum += l * val; sumsq += l * val * val; sumcb += l * val * val * val; sumqt += l * val * val * val * val; sum_abs += l * fabs(val); total_size += l; } } G_debug(3, "sum = %f total_size = %f", sum, total_size); } } } if (otype & GV_AREA) { nareas = Vect_get_num_areas(&Map); for (area = 1; area <= nareas; area++) { int i, centr; G_debug(3, "area = %d", area); centr = Vect_get_area_centroid(&Map, area); if (centr < 1) continue; G_debug(3, "centr = %d", centr); Vect_read_line(&Map, NULL, Cats, centr); for (i = 0; i < Cats->n_cats; i++) { if (Cats->field[i] == ofield) { double val; dbCatVal *catval; G_debug(3, "cat = %d", Cats->cat[i]); if (db_CatValArray_get_value (&Cvarr, Cats->cat[i], &catval) != DB_OK) { G_debug(3, "No record for cat = %d", Cats->cat[i]); nmissing++; continue; } if (catval->isNull) { G_debug(3, "NULL value for cat = %d", Cats->cat[i]); nnull++; continue; } if (ctype == DB_C_TYPE_INT) { val = catval->val.i; } else if (ctype == DB_C_TYPE_DOUBLE) { val = catval->val.d; } count++; if (first) { max = val; min = val; first = 0; } else { if (val > max) max = val; if (val < min) min = val; } if (compatible) { double a; a = Vect_get_area_area(&Map, area); sum += a * val; sumsq += a * val * val; sumcb += a * val * val * val; sumqt += a * val * val * val * val; sum_abs += a * fabs(val); total_size += a; } G_debug(4, "sum = %f total_size = %f", sum, total_size); } } } } G_debug(2, "sum = %f total_size = %f", sum, total_size); if (compatible) { if ((otype & GV_LINES) || (otype & GV_AREA)) { mean = sum / total_size; mean_abs = sum_abs / total_size; /* Roger Bivand says it is wrong see GRASS devel list 7/2004 */ /* pop_variance = (sumsq - sum*sum/total_size)/total_size; pop_stdev = sqrt(pop_variance); */ } else { double n = count; mean = sum / count; mean_abs = sum_abs / count; pop_variance = (sumsq - sum * sum / count) / count; pop_stdev = sqrt(pop_variance); pop_coeff_variation = pop_stdev / (sqrt(sum * sum) / count); sample_variance = (sumsq - sum * sum / count) / (count - 1); sample_stdev = sqrt(sample_variance); kurtosis = (sumqt / count - 4 * sum * sumcb / (n * n) + 6 * sum * sum * sumsq / (n * n * n) - 3 * sum * sum * sum * sum / (n * n * n * n)) / (sample_stdev * sample_stdev * sample_stdev * sample_stdev) - 3; skewness = (sumcb / n - 3 * sum * sumsq / (n * n) + 2 * sum * sum * sum / (n * n * n)) / (sample_stdev * sample_stdev * sample_stdev); } } G_debug(3, "otype %d:", otype); if (shell_flag->answer) { fprintf(stdout, "n=%d\n", count); fprintf(stdout, "nmissing=%d\n", nmissing); fprintf(stdout, "nnull=%d\n", nnull); if (count > 0) { fprintf(stdout, "min=%g\n", min); fprintf(stdout, "max=%g\n", max); fprintf(stdout, "range=%g\n", max - min); if (compatible && (otype & GV_POINTS)) { fprintf(stdout, "mean=%g\n", mean); fprintf(stdout, "mean_abs=%g\n", mean_abs); fprintf(stdout, "population_stddev=%g\n", pop_stdev); fprintf(stdout, "population_variance=%g\n", pop_variance); fprintf(stdout, "population_coeff_variation=%g\n", pop_coeff_variation); if (otype & GV_POINTS) { fprintf(stdout, "sample_stddev=%g\n", sample_stdev); fprintf(stdout, "sample_variance=%g\n", sample_variance); fprintf(stdout, "kurtosis=%g\n", kurtosis); fprintf(stdout, "skewness=%g\n", skewness); } } } } else { fprintf(stdout, "number of features with non NULL attribute: %d\n", count); fprintf(stdout, "number of missing attributes: %d\n", nmissing); fprintf(stdout, "number of NULL attributes: %d\n", nnull); if (count > 0) { fprintf(stdout, "minimum: %g\n", min); fprintf(stdout, "maximum: %g\n", max); fprintf(stdout, "range: %g\n", max - min); if (compatible && (otype & GV_POINTS)) { fprintf(stdout, "mean: %g\n", mean); fprintf(stdout, "mean of absolute values: %g\n", mean_abs); fprintf(stdout, "population standard deviation: %g\n", pop_stdev); fprintf(stdout, "population variance: %g\n", pop_variance); fprintf(stdout, "population coefficient of variation: %g\n", pop_coeff_variation); if (otype & GV_POINTS) { fprintf(stdout, "sample standard deviation: %g\n", sample_stdev); fprintf(stdout, "sample variance: %g\n", sample_variance); fprintf(stdout, "kurtosis: %g\n", kurtosis); fprintf(stdout, "skewness: %g\n", skewness); } } } } /* TODO: mode, skewness, kurtosis */ if (extended->answer && compatible && (otype & GV_POINTS) && count > 0) { double quartile_25 = 0.0, quartile_75 = 0.0, quartile_perc = 0.0; double median = 0.0; int qpos_25, qpos_75, qpos_perc; qpos_25 = (int)(count * 0.25 - 0.5); qpos_75 = (int)(count * 0.75 - 0.5); qpos_perc = (int)(count * perc / 100. - 0.5); if (db_CatValArray_sort_by_value(&Cvarr) != DB_OK) G_fatal_error(_("Cannot sort the key/value array")); if (Cvarr.ctype == DB_C_TYPE_INT) { quartile_25 = (Cvarr.value[qpos_25]).val.i; if (count % 2) /* odd */ median = (Cvarr.value[(int)(count / 2)]).val.i; else /* even */ median = ((Cvarr.value[count / 2 - 1]).val.i + (Cvarr.value[count / 2]).val.i) / 2.0; quartile_75 = (Cvarr.value[qpos_75]).val.i; quartile_perc = (Cvarr.value[qpos_perc]).val.i; } else { /* must be DB_C_TYPE_DOUBLE */ quartile_25 = (Cvarr.value[qpos_25]).val.d; if (count % 2) /* odd */ median = (Cvarr.value[(int)(count / 2)]).val.d; else /* even */ median = ((Cvarr.value[count / 2 - 1]).val.d + (Cvarr.value[count / 2]).val.d) / 2.0; quartile_75 = (Cvarr.value[qpos_75]).val.d; quartile_perc = (Cvarr.value[qpos_perc]).val.d; } if (shell_flag->answer) { fprintf(stdout, "first_quartile=%g\n", quartile_25); fprintf(stdout, "median=%g\n", median); fprintf(stdout, "third_quartile=%g\n", quartile_75); fprintf(stdout, "percentile_%d=%g\n", perc, quartile_perc); } else { fprintf(stdout, "1st quartile: %g\n", quartile_25); if (count % 2) fprintf(stdout, "median (odd number of cells): %g\n", median); else fprintf(stdout, "median (even number of cells): %g\n", median); fprintf(stdout, "3rd quartile: %g\n", quartile_75); if (perc % 10 == 1 && perc != 11) fprintf(stdout, "%dst percentile: %g\n", perc, quartile_perc); else if (perc % 10 == 2 && perc != 12) fprintf(stdout, "%dnd percentile: %g\n", perc, quartile_perc); else if (perc % 10 == 3 && perc != 13) fprintf(stdout, "%drd percentile: %g\n", perc, quartile_perc); else fprintf(stdout, "%dth percentile: %g\n", perc, quartile_perc); } } Vect_close(&Map); exit(EXIT_SUCCESS); }
void scan_z(struct Map_info *Map, int field, const char *style, const char *rules, const struct FPRange *range, struct Colors *colors) { int ltype, line, cat, i; int items_alloc; double zmin, zmax; struct line_pnts *Points; struct line_cats *Cats; struct Colors vcolors; dbCatValArray cvarr; Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); items_alloc = 0; db_CatValArray_init(&cvarr); cvarr.ctype = DB_C_TYPE_DOUBLE; Vect_set_constraint_field(Map, field); Vect_set_constraint_type(Map, GV_POINTS); /* points, centroids or kernels only) */ G_message(_("Reading features...")); line = i = 0; while(TRUE) { ltype = Vect_read_next_line(Map, Points, Cats); if (ltype == -1) G_fatal_error(_("Unable to read vector map")); if (ltype == -2) break; /* EOF */ G_progress(++line, 1e4); if (Vect_cat_get(Cats, field, &cat) == -1) continue; /* skip features without category */ /* add item into cat-value array */ if (i >= items_alloc) { items_alloc += 1000; db_CatValArray_realloc(&cvarr, items_alloc); } cvarr.n_values++; cvarr.value[i].cat = cat; cvarr.value[i++].val.d = Points->z[0]; if (line == 1 || Points->z[0] < zmin) zmin = Points->z[0]; if (line == 1 || Points->z[0] > zmax) zmax = Points->z[0]; } G_progress(1, 1); /* sort array by z-coordinate */ db_CatValArray_sort_by_value(&cvarr); if (range) { if (range->min >= zmin && range->min <= zmax) zmin = range->min; else G_warning(_("Min value (%f) is out of range %f,%f"), range->min, zmin, zmax); if (range->max <= zmax && range->max >= zmin) zmax = range->max; else G_warning(_("Max value (%f) is out of range %f,%f"), range->max, zmin, zmax); } if (style) make_colors(&vcolors, style, (DCELL) zmin, (DCELL) zmax, TRUE); else if (rules) { load_colors(&vcolors, rules, (DCELL) zmin, (DCELL) zmax, TRUE); } /* color table for categories */ color_rules_to_cats(&cvarr, TRUE, &vcolors, colors); Vect_destroy_line_struct(Points); Vect_destroy_cats_struct(Cats); db_CatValArray_free(&cvarr); }
int scan_attr(const struct Map_info *Map, int layer, const char *column_name, const char *style, const char *rules, const struct FPRange *range, struct Colors *colors) { int ctype, is_fp, nrec; double fmin, fmax; struct field_info *fi; struct Colors vcolors; dbDriver *driver; dbCatValArray cvarr; Rast_init_colors(colors); fi = Vect_get_field(Map, layer); if (!fi) G_fatal_error(_("Database connection not defined for layer %d"), layer); driver = db_start_driver_open_database(fi->driver, fi->database); if (!driver) G_fatal_error(_("Unable to open database <%s> by driver <%s>"), fi->database, fi->driver); db_set_error_handler_driver(driver); ctype = db_column_Ctype(driver, fi->table, column_name); if (ctype == -1) G_fatal_error(_("Column <%s> not found in table <%s>"), column_name, fi->table); if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("Column <%s> is not numeric"), column_name); is_fp = ctype == DB_C_TYPE_DOUBLE; nrec = db_select_CatValArray(driver, fi->table, fi->key, column_name, NULL, &cvarr); if (nrec < 1) { G_important_message(_("No data selected")); return 0; } /* color table for values */ db_CatValArray_sort_by_value(&cvarr); if (is_fp) { fmin = cvarr.value[0].val.d; fmax = cvarr.value[cvarr.n_values-1].val.d; if (range) { if (range->min >= fmin && range->min <= fmax) fmin = range->min; else G_warning(_("Min value (%f) is out of range %f,%f"), range->min, fmin, fmax); if (range->max <= fmax && range->max >= fmin) fmax = range->max; else G_warning(_("Max value (%f) is out of range %f,%f"), range->max, fmin, fmax); } } else { fmin = cvarr.value[0].val.i; fmax = cvarr.value[cvarr.n_values-1].val.i; if (range) { if (range->min >= fmin && range->min <= fmax) fmin = range->min; else G_warning(_("Min value (%d) is out of range %d,%d"), (int) range->min, (int) fmin, (int) fmax); if (range->max <= fmax && range->max >= fmin) fmax = range->max; else G_warning(_("Max value (%d) is out of range %d,%d"), (int) range->max, (int) fmin, (int) fmax); } } if (style) make_colors(&vcolors, style, (DCELL) fmin, (DCELL) fmax, is_fp); else if (rules) load_colors(&vcolors, rules, (DCELL) fmin, (DCELL) fmax, is_fp); /* color table for categories */ color_rules_to_cats(&cvarr, is_fp, &vcolors, colors); db_close_database(driver); return is_fp; }
int main(int argc, char *argv[]) { struct GModule *module; struct Option *map_opt, *field_opt, *col_opt, *where_opt; struct Option *algo_opt, *nbclass_opt; struct Flag *shell_flag; struct Map_info Map; struct field_info *Fi; dbDriver *Driver; dbCatValArray Cvarr; int ofield; int nrec, ctype, nbclass, nbreaks, *frequencies; int ret, i; double finfo; double *classbreaks, min, max, *data; struct GASTATS stats; char *desc; module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("classification")); G_add_keyword(_("attribute table")); G_add_keyword(_("statistics")); module->description = _("Classifies attribute data, e.g. for thematic mapping"); map_opt = G_define_standard_option(G_OPT_V_MAP); field_opt = G_define_standard_option(G_OPT_V_FIELD); col_opt = G_define_standard_option(G_OPT_DB_COLUMN); col_opt->required = YES; col_opt->description = _("Column name or expression"); where_opt = G_define_standard_option(G_OPT_DB_WHERE); algo_opt = G_define_option(); algo_opt->key = "algorithm"; algo_opt->type = TYPE_STRING; algo_opt->required = YES; algo_opt->multiple = NO; algo_opt->options = "int,std,qua,equ,dis"; algo_opt->description = _("Algorithm to use for classification"); desc = NULL; G_asprintf(&desc, "int;%s;" "std;%s;" "qua;%s;" "equ;%s", /* "dis;%s" */ _("simple intervals"), _("standard deviations"), _("quantiles"), _("equiprobable (normal distribution)")); /* _("discontinuities"));currently disabled because of bugs */ algo_opt->descriptions = desc; nbclass_opt = G_define_option(); nbclass_opt->key = "nbclasses"; nbclass_opt->type = TYPE_INTEGER; nbclass_opt->required = YES; nbclass_opt->multiple = NO; nbclass_opt->description = _("Number of classes to define"); shell_flag = G_define_flag(); shell_flag->key = 'g'; shell_flag->description = _("Print only class breaks (without min and max)"); G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* open input vector */ Vect_set_open_level(2); if (Vect_open_old2(&Map, map_opt->answer, "", field_opt->answer) < 0) G_fatal_error(_("Unable to open vector map <%s>"), map_opt->answer); ofield = Vect_get_field_number(&Map, field_opt->answer); /* Read attributes */ db_CatValArray_init(&Cvarr); Fi = Vect_get_field(&Map, ofield); if (Fi == NULL) { G_fatal_error(_("Unable to get layer info for vector map")); } Vect_close(&Map); Driver = db_start_driver_open_database(Fi->driver, Fi->database); if (Driver == NULL) G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Fi->database, Fi->driver); /* Note: do not check if the column exists in the table because it may be an expression */ nrec = db_select_CatValArray(Driver, Fi->table, Fi->key, col_opt->answer, where_opt->answer, &Cvarr); G_debug(2, "nrec = %d", nrec); ctype = Cvarr.ctype; if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("Column type not supported")); if (nrec < 0) G_fatal_error(_("Unable to select data from table")); db_close_database_shutdown_driver(Driver); ret = db_CatValArray_sort_by_value(&Cvarr); if (ret == DB_FAILED) G_fatal_error(_("Unable to sort array of values")); data = (double *)G_malloc((nrec) * sizeof(double)); for (i = 0; i < nrec; i++) data[i] = 0.0; if (ctype == DB_C_TYPE_INT) { for (i = 0; i < nrec; i++) data[i] = Cvarr.value[i].val.i; } else { for (i = 0; i < nrec; i++) data[i] = Cvarr.value[i].val.d; } nbclass = atoi(nbclass_opt->answer); nbreaks = nbclass - 1; /* we need one less classbreaks (min and max exluded) than classes */ classbreaks = (double *)G_malloc((nbreaks) * sizeof(double)); for (i = 0; i < nbreaks; i++) classbreaks[i] = 0; /* Get classbreaks for given algorithm and number of classbreaks. * finfo takes any info coming from the classification algorithms * equ algorithm can alter number of class breaks */ finfo = class_apply_algorithm(algo_opt->answer, data, nrec, &nbreaks, classbreaks); if (G_strcasecmp(algo_opt->answer, "dis") == 0 && finfo < 3.84148) G_warning(_("The discontinuities algorithm indicates that some " "class breaks are not statistically significant at " "alpha=0.05. You are advised to reduce the number of classes.")); /*output to be piped to other modules ? */ if (shell_flag->answer) { for (i = 0; i < nbreaks - 1; i++) fprintf(stdout, "%f,", classbreaks[i]); fprintf(stdout, "%f", classbreaks[nbreaks - 1]); fprintf(stdout, "\n"); } else { frequencies = (int *)G_malloc((nbreaks + 1) * sizeof(int)); for (i = 0; i < nbreaks + 1; i++) frequencies[i] = 0; ret = class_frequencies(data, nrec, nbreaks, classbreaks, frequencies); basic_stats(data, nrec, &stats); min = data[0]; max = data[nrec - 1]; /* as equ algorithm can modify number of breaks we recalculate number of * classes */ fprintf(stdout, _("\nClassification of %s into %i classes\n"), col_opt->answer, nbreaks + 1); fprintf(stdout, _("Using algorithm: *** %s ***\n"), algo_opt->answer); fprintf(stdout, _("Mean: %f\tStandard deviation = %f\n"), stats.mean, stats.stdev); if (G_strcasecmp(algo_opt->answer, "dis") == 0) { fprintf(stdout, _("Lowest chi2 = %f\n"), finfo); } if (G_strcasecmp(algo_opt->answer, "std") == 0) fprintf(stdout, _("Stdev multiplied by %.4f to define step\n"), finfo); fprintf(stdout, "\n"); fprintf(stdout, _("%15s%15s%15s\n\n"), "From (excl.)", "To (incl.)", "Frequency"); fprintf(stdout, "%15.5f%15.5f%15i\n", min, classbreaks[0], frequencies[0]); for (i = 1; i < nbreaks; i++) { fprintf(stdout, "%15.5f%15.5f%15i\n", classbreaks[i - 1], classbreaks[i], frequencies[i]); } fprintf(stdout, "%15.5f%15.5f%15i\n", classbreaks[nbreaks - 1], max, frequencies[nbreaks]); fprintf(stdout, _("\nNote: Minimum of first class is including\n\n")); } fflush(stdout); exit(EXIT_SUCCESS); }
void summary(void) { if (compatible) { if (!geometry->answer && weight_flag->answer) { mean = sum / total_size; mean_abs = sum_abs / total_size; /* Roger Bivand says it is wrong see GRASS devel list 7/2004 */ /* pop_variance = (sumsq - sum * sum / total_size) / total_size; pop_stdev = sqrt(pop_variance); pop_coeff_variation = pop_stdev / (sqrt(sum * sum) / count); */ } else { double n = count; mean = sum / count; mean_abs = sum_abs / count; pop_variance = (sumsq - sum * sum / count) / count; pop_stdev = sqrt(pop_variance); pop_coeff_variation = pop_stdev / (sqrt(sum * sum) / count); sample_variance = (sumsq - sum * sum / count) / (count - 1); sample_stdev = sqrt(sample_variance); kurtosis = (sumqt / count - 4 * sum * sumcb / (n * n) + 6 * sum * sum * sumsq / (n * n * n) - 3 * sum * sum * sum * sum / (n * n * n * n)) / (sample_stdev * sample_stdev * sample_stdev * sample_stdev) - 3; skewness = (sumcb / n - 3 * sum * sumsq / (n * n) + 2 * sum * sum * sum / (n * n * n)) / (sample_stdev * sample_stdev * sample_stdev); } } G_debug(3, "otype %d:", otype); if (shell_flag->answer) { fprintf(stdout, "n=%d\n", count); if (geometry->answer) { fprintf(stdout, "nzero=%d\n", nzero); } else { fprintf(stdout, "nmissing=%d\n", nmissing); fprintf(stdout, "nnull=%d\n", nnull); } if (count > 0) { fprintf(stdout, "min=%g\n", min); fprintf(stdout, "max=%g\n", max); fprintf(stdout, "range=%g\n", max - min); fprintf(stdout, "sum=%g\n", sum); if (compatible) { fprintf(stdout, "mean=%g\n", mean); fprintf(stdout, "mean_abs=%g\n", mean_abs); if (geometry->answer || !weight_flag->answer) { fprintf(stdout, "population_stddev=%g\n", pop_stdev); fprintf(stdout, "population_variance=%g\n", pop_variance); fprintf(stdout, "population_coeff_variation=%g\n", pop_coeff_variation); fprintf(stdout, "sample_stddev=%g\n", sample_stdev); fprintf(stdout, "sample_variance=%g\n", sample_variance); fprintf(stdout, "kurtosis=%g\n", kurtosis); fprintf(stdout, "skewness=%g\n", skewness); } } } } else { if (geometry->answer) { fprintf(stdout, "number of primitives: %d\n", nlines); fprintf(stdout, "number of non zero distances: %d\n", count); fprintf(stdout, "number of zero distances: %d\n", nzero); } else { fprintf(stdout, "number of features with non NULL attribute: %d\n", count); fprintf(stdout, "number of missing attributes: %d\n", nmissing); fprintf(stdout, "number of NULL attributes: %d\n", nnull); } if (count > 0) { fprintf(stdout, "minimum: %g\n", min); fprintf(stdout, "maximum: %g\n", max); fprintf(stdout, "range: %g\n", max - min); fprintf(stdout, "sum: %g\n", sum); if (compatible) { fprintf(stdout, "mean: %g\n", mean); fprintf(stdout, "mean of absolute values: %g\n", mean_abs); if (geometry->answer || !weight_flag->answer) { fprintf(stdout, "population standard deviation: %g\n", pop_stdev); fprintf(stdout, "population variance: %g\n", pop_variance); fprintf(stdout, "population coefficient of variation: %g\n", pop_coeff_variation); fprintf(stdout, "sample standard deviation: %g\n", sample_stdev); fprintf(stdout, "sample variance: %g\n", sample_variance); fprintf(stdout, "kurtosis: %g\n", kurtosis); fprintf(stdout, "skewness: %g\n", skewness); } } } } /* TODO: mode, skewness, kurtosis */ /* Not possible to calculate for point distance, since we don't collect the population */ if (ext_flag->answer && compatible && ((otype & GV_POINTS) || !weight_flag->answer) && !geometry->answer && count > 0) { double quartile_25 = 0.0, quartile_75 = 0.0, quartile_perc = 0.0; double median = 0.0; int qpos_25, qpos_75, qpos_perc; qpos_25 = (int)(count * 0.25 - 0.5); qpos_75 = (int)(count * 0.75 - 0.5); qpos_perc = (int)(count * perc / 100. - 0.5); if (db_CatValArray_sort_by_value(&Cvarr) != DB_OK) G_fatal_error(_("Cannot sort the key/value array")); if (Cvarr.ctype == DB_C_TYPE_INT) { quartile_25 = (Cvarr.value[qpos_25]).val.i; if (count % 2) /* odd */ median = (Cvarr.value[(int)(count / 2)]).val.i; else /* even */ median = ((Cvarr.value[count / 2 - 1]).val.i + (Cvarr.value[count / 2]).val.i) / 2.0; quartile_75 = (Cvarr.value[qpos_75]).val.i; quartile_perc = (Cvarr.value[qpos_perc]).val.i; } else { /* must be DB_C_TYPE_DOUBLE */ quartile_25 = (Cvarr.value[qpos_25]).val.d; if (count % 2) /* odd */ median = (Cvarr.value[(int)(count / 2)]).val.d; else /* even */ median = ((Cvarr.value[count / 2 - 1]).val.d + (Cvarr.value[count / 2]).val.d) / 2.0; quartile_75 = (Cvarr.value[qpos_75]).val.d; quartile_perc = (Cvarr.value[qpos_perc]).val.d; } if (shell_flag->answer) { fprintf(stdout, "first_quartile=%g\n", quartile_25); fprintf(stdout, "median=%g\n", median); fprintf(stdout, "third_quartile=%g\n", quartile_75); fprintf(stdout, "percentile_%d=%g\n", perc, quartile_perc); } else { fprintf(stdout, "1st quartile: %g\n", quartile_25); if (count % 2) fprintf(stdout, "median (odd number of cells): %g\n", median); else fprintf(stdout, "median (even number of cells): %g\n", median); fprintf(stdout, "3rd quartile: %g\n", quartile_75); if (perc % 10 == 1 && perc != 11) fprintf(stdout, "%dst percentile: %g\n", perc, quartile_perc); else if (perc % 10 == 2 && perc != 12) fprintf(stdout, "%dnd percentile: %g\n", perc, quartile_perc); else if (perc % 10 == 3 && perc != 13) fprintf(stdout, "%drd percentile: %g\n", perc, quartile_perc); else fprintf(stdout, "%dth percentile: %g\n", perc, quartile_perc); } } }
/*! \brief Lines z-bulk labeling Automated labeling (z coordinate assignment) of vector lines (iso-lines). \param Map pointer to Map_info \param List list of selected lines \param point_start_end staring and ending point \param start starting value \param step step value \return number of modified features \return -1 on error */ int Vedit_bulk_labeling(struct Map_info *Map, struct ilist *List, double x1, double y1, double x2, double y2, double start, double step) { int i, cv_i, p_i; int line, type, temp_line; int nlines_modified; double value, dist; struct line_cats *Cats; struct line_pnts *Points, *Points_se; /* start - end */ struct bound_box box, box_se; /* for intersection */ struct line_pnts **Points_a, **Points_b; int nlines_a, nlines_b; dbCatValArray cv; /* line_id / dist */ nlines_modified = 0; value = start; Points = Vect_new_line_struct(); Points_se = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); db_CatValArray_alloc(&cv, List->n_values); cv.ctype = DB_C_TYPE_DOUBLE; cv.n_values = 0; Vect_append_point(Points_se, x1, y1, -PORT_DOUBLE_MAX); Vect_append_point(Points_se, x2, y2, PORT_DOUBLE_MAX); /* write temporaly line */ temp_line = Vect_write_line(Map, GV_LINE, Points_se, Cats); if (temp_line < 0) { return -1; } Vect_line_box(Points_se, &box_se); /* determine order of lines */ cv_i = 0; for (i = 0; i < List->n_values; i++) { line = List->value[i]; if (!Vect_line_alive(Map, line)) continue; type = Vect_read_line(Map, Points, NULL, line); if (!(type & GV_LINE)) continue; Vect_line_box(Points, &box); if (Vect_line_check_intersection(Points_se, Points, WITH_Z)) { Vect_line_intersection(Points_se, Points, &box_se, &box, &Points_a, &Points_b, &nlines_a, &nlines_b, WITHOUT_Z); if (nlines_a < 2 || nlines_b < 1) /* should not happen */ continue; /* calculate distance start point -> point of intersection */ for (p_i = 0; p_i < Points_a[0]->n_points; p_i++) { Points_a[0]->z[p_i] = 0; } dist = Vect_line_length(Points_a[0]); /* always first line in array? */ cv.value[cv_i].cat = line; cv.value[cv_i++].val.d = dist; cv.n_values++; } } /* sort array by distance */ db_CatValArray_sort_by_value(&cv); /* z bulk-labeling */ for (cv_i = 0; cv_i < cv.n_values; cv_i++) { line = cv.value[cv_i].cat; type = Vect_read_line(Map, Points, Cats, line); for (p_i = 0; p_i < Points->n_points; p_i++) { Points->z[p_i] = value; } if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) { return -1; } nlines_modified++; value += step; } if (Vect_delete_line(Map, temp_line) < 0) { return -1; } db_CatValArray_free(&cv); Vect_destroy_line_struct(Points); Vect_destroy_line_struct(Points_se); Vect_destroy_cats_struct(Cats); return nlines_modified; }