X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fmath%2Forder-stats.c;fp=src%2Fmath%2Forder-stats.c;h=3f6b8fcfbb64d9538ff56b38bd2bc03c52198590;hb=b9f712f8911170fcc049c6d7d83b6887185de4dd;hp=2ec7c1a0d476f43bf8d4889ab1b3986f515af934;hpb=2a76184b55a8c229adc0b31d3436d29076de0ef8;p=pspp diff --git a/src/math/order-stats.c b/src/math/order-stats.c index 2ec7c1a0d4..3f6b8fcfbb 100644 --- a/src/math/order-stats.c +++ b/src/math/order-stats.c @@ -18,6 +18,7 @@ #include "math/order-stats.h" +#include #include #include "data/casereader.h" @@ -86,10 +87,8 @@ update_k_values (const struct ccase *cx, double y_i, double c_i, double cc_i, } } - if (stat->accumulate) - stat->accumulate (stat, cx, c_i, cc_i, y_i); - - tos->cc = cc_i; + if (tos->accumulate) + tos->accumulate (stat, cx, c_i, cc_i, y_i); } } @@ -97,6 +96,8 @@ update_k_values (const struct ccase *cx, double y_i, double c_i, double cc_i, order statistics in OS, taking data from case index DATA_IDX and weights from case index WEIGHT_IDX. WEIGHT_IDX may be -1 to assume weight 1. + This function must be used only once per order_stats. + Takes ownership of READER. Data values must be numeric and sorted in ascending order. Use @@ -117,29 +118,37 @@ order_stats_accumulate_idx (struct order_stats **os, size_t n_os, for (; (cx = casereader_read (reader)) != NULL; case_unref (cx)) { const double weight = weight_idx == -1 ? 1.0 : case_num_idx (cx, weight_idx); - if (weight == SYSMIS) + if (weight == SYSMIS || weight <= 0) continue; const double this_value = case_num_idx (cx, data_idx); - assert (this_value >= prev_value); + if (!isfinite (this_value) || this_value == SYSMIS) + continue; - if (prev_value == -DBL_MAX || prev_value == this_value) - c_i += weight; + if (!prev_cx || this_value > prev_value) + { + if (prev_cx) + update_k_values (prev_cx, prev_value, c_i, cc_i, os, n_os); + prev_value = this_value; + c_i = weight; + } + else + { + /* Data values must be sorted. */ + assert (this_value == prev_value); + + c_i += weight; + } - if (prev_value > -DBL_MAX && this_value > prev_value) - { - update_k_values (prev_cx, prev_value, c_i, cc_i, os, n_os); - c_i = weight; - } - - case_unref (prev_cx); cc_i += weight; - prev_value = this_value; + case_unref (prev_cx); prev_cx = case_ref (cx); } - - update_k_values (prev_cx, prev_value, c_i, cc_i, os, n_os); - case_unref (prev_cx); + if (prev_cx) + { + update_k_values (prev_cx, prev_value, c_i, cc_i, os, n_os); + case_unref (prev_cx); + } casereader_destroy (reader); } @@ -149,6 +158,8 @@ order_stats_accumulate_idx (struct order_stats **os, size_t n_os, WEIGHT_VAR. Drops cases for which the value of DATA_VAR is missing according to EXCLUDE. WEIGHT_VAR may be NULL to assume weight 1. + This function must be used only once per order_stats. + Takes ownership of READER. DATA_VAR must be numeric and sorted in ascending order. Use