/* Given a sorted array of doubles, return the MAD value (median absolute deviation), with scale constant 'scale' */ long double _GL_ATTRIBUTE_PURE mad_value (const long double * const values, size_t n, double scale) { const long double median = median_value (values,n); long double *mads = xnmalloc (n,sizeof (long double)); long double mad = 0 ; for (size_t i=0; i<n; ++i) mads[i] = fabsl (median - values[i]); qsortfl (mads,n); mad = median_value (mads,n); free (mads); return mad * scale; }
void calc_minmax_median(const char *inFile, char *band, double mask, double *min, double *max) { long long ii, jj; float logeps = 10.0 * log10(EPSILON); float median, median0; meta_parameters *meta = meta_read(inFile); int band_number = (!band || strlen(band) == 0 || strcmp(band, "???") == 0) ? 0 : get_band_number(meta->general->bands, meta->general->band_count, band); long sample_count = meta->general->sample_count; long line_count = meta->general->line_count; long pixel_count = sample_count*line_count; long offset = line_count * band_number; float *data_line = MALLOC(sizeof(float) * sample_count); float *data = MALLOC(sizeof(float) * pixel_count); float *data2 = MALLOC(sizeof(float) * pixel_count); // Culling invalid pixels FILE *fp = FOPEN(inFile, "rb"); long valid_pixel_count = 0; asfPrintStatus("\nCalculating min and max using median...\n"); for (ii=0; ii<line_count; ++ii) { get_float_line(fp, meta, ii + offset, data_line); asfPercentMeter(((double)ii/(double)line_count)); for (jj=0; jj<sample_count; ++jj) { if (!FLOAT_EQUIVALENT(data_line[jj], -9999.99) || !FLOAT_EQUIVALENT(data_line[jj], logeps) || ISNAN(mask)) { data[valid_pixel_count] = data_line[jj]; valid_pixel_count++; } } } asfPercentMeter(1.0); FCLOSE(fp); FREE(data_line); // Determine initial min and max *min = INIT_MINMAX; *max = -INIT_MINMAX; float minmin = INIT_MINMAX; float maxmax = -INIT_MINMAX; for (ii=0; ii<valid_pixel_count; ++ii) { data2[ii] = data[ii]; if (data[ii] < minmin) minmin = data[ii]; if (data[ii] > maxmax) maxmax = data[ii]; } median0 = median_value(data, valid_pixel_count); // Determine minimum median = median0; *min = median0; for (ii=0; ii<3; ii++) { pixel_count = -1; for (jj=0; jj<valid_pixel_count; ++jj) if (median0 == minmin) { if (data[jj] <= median) { pixel_count++; data2[pixel_count] = data[jj]; } } else { if (data[jj] < median) { pixel_count++; data2[pixel_count] = data[jj]; } } median = median_value(data2, pixel_count); if (median == minmin) median = *min; *min = median; } // Determine maximum median = median0; *max = median0; for (ii=0; ii<3; ii++) { pixel_count = -1; for (jj=0; jj<valid_pixel_count; ++jj) if (median0 == maxmax) { if (data[jj] >= median) { pixel_count++; data2[pixel_count] = data[jj]; } } else { if (data[jj] > median) { pixel_count++; data2[pixel_count] = data[jj]; } } median = median_value(data2, pixel_count); if (median == maxmax) median = *max; *max = median; } FREE(data); FREE(data2); }
/* Prints to stdout the result of the field operation, based on collected values */ void field_op_summarize (struct fieldop *op) { bool print_numeric_result = true; long double numeric_result = 0 ; char *string_result = NULL; #ifdef ENABLE_DEBUG if (debug) fprintf (stderr, "-- summarize for %s(%zu)\n", op->name, op->field); #endif switch (op->op) { case OP_MEAN: numeric_result = op->value / op->count; break; case OP_SUM: case OP_COUNT: case OP_MIN: case OP_MAX: case OP_ABSMIN: case OP_ABSMAX: /* no summarization for these operations, just print the value */ numeric_result = op->value; break; case OP_MEDIAN: field_op_sort_values (op); numeric_result = median_value ( op->values, op->num_values ); break; case OP_PSTDEV: numeric_result = stdev_value ( op->values, op->num_values, DF_POPULATION); break; case OP_SSTDEV: numeric_result = stdev_value ( op->values, op->num_values, DF_SAMPLE); break; case OP_PVARIANCE: numeric_result = variance_value ( op->values, op->num_values, DF_POPULATION); break; case OP_SVARIANCE: numeric_result = variance_value ( op->values, op->num_values, DF_SAMPLE); break; case OP_MODE: case OP_ANTIMODE: field_op_sort_values (op); numeric_result = mode_value ( op->values, op->num_values, (op->op==OP_MODE)?MODE:ANTIMODE); break; case OP_UNIQUE: print_numeric_result = false; string_result = unique_value (op, case_sensitive); break; case OP_COLLAPSE: print_numeric_result = false; string_result = collapse_value (op); break; case OP_COUNT_UNIQUE: numeric_result = count_unique_values(op,case_sensitive); break; default: /* Should never happen */ error (EXIT_FAILURE, 0, _("internal error 2")); } #ifdef ENABLE_DEBUG if (debug) { if (print_numeric_result) fprintf (stderr, "%s(%zu) = %Lg\n", op->name, op->field, numeric_result); else fprintf (stderr, "%s(%zu) = '%s'\n", op->name, op->field, string_result); } #endif if (print_numeric_result) printf ("%Lg", numeric_result); else printf ("%s", string_result); free (string_result); }