#include "libpspp/hmap.h"
#include "libpspp/message.h"
#include "libpspp/string-array.h"
+#include "math/mode.h"
#include "math/moments.h"
#include "math/percentiles.h"
#include "math/sort.h"
/* MEAN, SEMEAN, STDDEV, SUM, VARIANCE, *.SUM. */
struct moments1 *moments;
+ /* MEDIAN, MODE, PTILE. */
struct
{
struct casewriter *writer;
- double mvalid;
- double median;
+ double ovalid;
+ double ovalue;
};
- /* XXX percentiles, mode, multiple response */
+ /* XXX multiple response */
};
static void
break;
case CTSF_MEDIAN:
+ case CTSF_MODE:
+ case CTSF_PTILE:
{
struct caseproto *proto = caseproto_create ();
proto = caseproto_add_width (proto, 0);
subcase_uninit (&ordering);
caseproto_unref (proto);
- s->mvalid = 0;
- s->median = SYSMIS;
+ s->ovalid = 0;
+ s->ovalue = SYSMIS;
}
break;
- case CTSF_MODE:
- case CTSF_PTILE:
- NOT_REACHED ();
-
case CTSF_RESPONSES:
case CTSF_ROWPCT_RESPONSES:
case CTSF_COLPCT_RESPONSES:
break;
case CTSF_MEDIAN:
- casewriter_destroy (s->writer);
- break;
-
case CTSF_MODE:
case CTSF_PTILE:
- NOT_REACHED ();
+ casewriter_destroy (s->writer);
+ break;
case CTSF_RESPONSES:
case CTSF_ROWPCT_RESPONSES:
break;
case CTSF_MEDIAN:
+ case CTSF_MODE:
+ case CTSF_PTILE:
if (var_is_value_missing (var, value))
{
- s->mvalid += weight;
+ s->ovalid += weight;
struct ccase *c = case_create (casewriter_get_proto (s->writer));
*case_num_rw_idx (c, 0) = value->f;
}
break;
- case CTSF_MODE:
- case CTSF_PTILE:
- NOT_REACHED ();
-
case CTSF_RESPONSES:
case CTSF_ROWPCT_RESPONSES:
case CTSF_COLPCT_RESPONSES:
NOT_REACHED ();
case CTSF_MEDIAN:
+ case CTSF_PTILE:
if (s->writer)
{
struct casereader *reader = casewriter_make_reader (s->writer);
s->writer = NULL;
- struct percentile *median = percentile_create (0.5, s->mvalid);
- struct order_stats *os = &median->parent;
+ struct percentile *ptile = percentile_create (
+ ss->function == CTSF_PTILE ? ss->percentile : 0.5, s->ovalid);
+ struct order_stats *os = &ptile->parent;
order_stats_accumulate_idx (&os, 1, reader, 1, 0);
- s->median = percentile_calculate (median, PC_HAVERAGE);
- statistic_destroy (&median->parent.parent);
+ s->ovalue = percentile_calculate (ptile, PC_HAVERAGE);
+ statistic_destroy (&ptile->parent.parent);
}
- return s->median;
+ return s->ovalue;
case CTSF_MODE:
- case CTSF_PTILE:
- NOT_REACHED ();
+ if (s->writer)
+ {
+ struct casereader *reader = casewriter_make_reader (s->writer);
+ s->writer = NULL;
+
+ struct mode *mode = mode_create ();
+ struct order_stats *os = &mode->parent;
+ order_stats_accumulate_idx (&os, 1, reader, 1, 0);
+ s->ovalue = mode->mode;
+ statistic_destroy (&mode->parent.parent);
+ }
+ return s->ovalue;
case CTSF_RESPONSES:
case CTSF_ROWPCT_RESPONSES: